<commit_before>/* Copyright 2015-2016 Sébastien Maccagnoni-Munch
 *
 * This file is part of AwesomeShop.
 *
 * AwesomeShop is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * AwesomeShop is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with AwesomeShop. If not, see <http://www.gnu.org/licenses/>.
 */
angular.module('awesomeshop', [
        // External modules
        'duScroll', 'ngAnimate', 'ngStorage', 'ui.bootstrap', 'ui.router',
        // Common awesomeshop modules
        'authentication', 'config', 'spinner',
        // Shop modules
        'shopPage', 'shopUser',
        'shopShop'
])
.config(function($locationProvider, $interpolateProvider, $urlRouterProvider, $urlMatcherFactoryProvider) {
    $locationProvider.html5Mode(true);
    $interpolateProvider.startSymbol('[[');
    $interpolateProvider.endSymbol(']]');
    $urlRouterProvider.otherwise('/');
    $urlMatcherFactoryProvider.strictMode(false);
})
.filter('trusthtml', function($sce) {
    return $sce.trustAsHtml;
})
.filter('htmlbr', function($sce) {
    return function(input) {
        if (input) {
            return $sce.trustAsHtml(input.replace(/\n/g, '
'));
        };
    };
})
.factory('translation', function($http) {
    var translations;
    $http.get('/messages')
        .then(function(response) {
            translations = response.data;
        });
    return function (message) {
        if (translations) {
            return translations[message] || message;
        } else {
            return message;
        };
    };
})
.filter('translate', function(translation) {
    return function(input) {
        return translation(input);
    }
})
.factory('countries', function($http) {
    var countries;
    $http.get('/api/country')
        .then(function(response) {
            countries = response.data;
        });
    return {
        get: function() {
            return countries;
        }
    };
})
.factory('newproducts', function($http) {
    var newproducts;
    $http.get('/api/newproducts')
        .then(function(response) {
            newproducts = response.data;
        });
    return {
        get: function() {
            return newproducts;
        },
        count: function() {
            if (newproducts) {
                return newproducts.length;
            } else {
                return 0;
            };
        }
    };
})
.factory('products', function($http, $q, $httpParamSerializer) {
    var catslugs = {},
        products = {};
    function get_product(productid, data, resolve, reject) {
        var prod;
        if (products[productid]) {
            prod = products[productid][data];
        };
        if (prod) {
            resolve(angular.copy(prod));
        } else {
            if (data) {
                params = {data: data};
            } else {
                params = {};
            }
            $http.get('/api/product/'+productid, {params: params})
                .then(function(response) {
                    var prod = response.data;
                    if (!products[prod.id]) {
                        products[prod.id] = {};
                    };
                    products[prod.id][data] = prod;
                    resolve(angular.copy(prod));
                }, reject);
        };
    };
    return {
        getid: function(productid, data, scope) {
            return $q(function(resolve, reject) {
                get_product(productid, data, resolve, reject);
            })
        },
        getcatslug: function(cat, slug, data) {
            var catslug = cat+'/'+slug;
            return $q(function(resolve, reject) {
                var productid = catslugs[catslug];
                if (productid) {
                    // This product is already known
                    get_product(productid, data, resolve, reject);
                } else {
                    // Download from the catslug
                    if (data) {
                        params = {data: data};
                    } else {
                        params = {};
                    }
                    $http.get('/api/product/catslug/'+catslug, {params: params})
                        .then(function(response) {
                            var prod = response.data;
                            if (!products[prod.id]) {
                                products[prod.id] = {};
                            };
                            products[prod.id][data] = prod;
                            catslugs[catslug] = prod.id;
                            get_product(prod.id, data, resolve, reject);
                        }, reject);
                };
            })
        }
    };
})
.factory('categories', function($rootScope, $http) {
    var categories,
        current_product_category;
    $http.get('/api/category', {params: {'flat':'true'}})
        .then(function(response) {
            categories = response.data;
        });
    $rootScope.$on('$stateChangeStart', function() {
        current_product_category = undefined;
    });
    $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams) {
        if (toState.name == 'product') {
            current_product_category = toParams.category;
        };
    });
    return {
        get: function() {
            return categories;
        },
        from_current_product() {
            return current_product_category;
        }
    };
})
.factory('docs', function($http) {
    var docs;
    $http.get('/api/page-doc')
        .then(function(response) {
            docs = response.data;
        });
    return {
        get: function() {
            return docs;
        }
    };
})
.factory('infos', function($http) {
    var infos;
    $http.get('/api/page-info')
        .then(function(response) {
            infos = response.data;
        });
    return {
        get: function() {
            return infos;
        }
    };
})
.factory('user', function($rootScope, $state, $http, $uibModal) {
    var user = undefined;
    $http.get('/api/userdata')
        .then(function(response) {
            user = response.data;
            if (response.data.auth) {
                $rootScope.$broadcast('event:auth-loginConfirmed', response.data);
            };
        });
    $rootScope.$on('event:auth-loginConfirmed', function(e, data) {
        user = data;
    });
    return {
        forcelogin: function() {
            $http.get('/api/forcelogin');
        },
        get: function() {
            return user;
        },
        set: function(data) {
            user = data;
        },
        logout: function() {
            $http.get('/api/logout')
                .then(function(response) {
                    user = response.data;
                    $state.go('index');
                });
        },
        resend_confirmation: function() {
            $http.get('/api/register/resend');
        },
        setlang: function(lang) {
            $http.put('/api/setlang', {'lang': lang})
                .then(function() {
                    window.location.reload();
                })
        }
    }
})
.factory('savedCarts', function($rootScope, $timeout, $http, cart, user) {
    var carts;
    function get_saved_carts() {
        $http.get('/api/cart')
            .then(function(response) {
                carts = response.data;
            });
    };
    if (user.get()) {
        get_saved_carts();
    };
    $rootScope.$on('event:auth-loginConfirmed', function(e, data) {
        // Timeout, just to be sure it is executed after the user data is loaded
        $timeout(function() {
            get_saved_carts();
        }, 10);
    });
    return {
        get: function() {
            return carts;
        },
        add: function(cart) {
            carts.push(cart);
        },
        count: function() {
            if (carts) {
                return carts.length;
            } else {
                return '';
            };
        },
        remove: function(index) {
            $http.delete('/api/cart/'+carts[index].id)
                .then(function() {
                    carts.splice(index, 1);
                })
        }
    };
})
.factory('cart', function($localStorage, $http, $state, products) {
    if ($localStorage.cart) {
        // Ask the server to adjust the cart (availability and price)
        $http.post('/api/cart/verify', $localStorage.cart)
            .then(function(response) {
                $localStorage.cart = response.data;
            });
    } else {
        $localStorage.cart = [];
    };
    return {
        add: function(productid, data, quantity) {
            // Add a product to the cart
            products.getid(productid, data)
                .then(function(prod) {
                    for (var i=0; i<$localStorage.cart.length; i++) {
                        var cartline = $localStorage.cart[i];
                        if (cartline.product.id == prod.id &&
                            cartline.data == data) {
                                cartline.quantity += quantity;
                                return;
                        }
                    };
                    // Product was not found, adding it
                    $localStorage.cart.push({
                        product: prod,
                        data: data,
                        quantity: quantity
                    })
                })
        },
        remove: function(productid, data) {
            // Completely remove the product from the cart
            for (var i=0; i<$localStorage.cart.length; i++) {
                if ($localStorage.cart[i].product.id == productid &&
                    $localStorage.cart[i].data == data) {
                        $localStorage.cart.splice(i, 1);
                        break;
                };
            };
        },
        load: function(cart, do_not_verify) {
            // Load a stored cart in the live cart
            // do_not_verify = False, ask the server to confirm the quantity in cart
            if (do_not_verify) {
                $localStorage.cart = cart;
            } else {
                $http.post('/api/cart/verify', cart)
                    .then(function(response) {
                        $localStorage.cart = response.data;
                    });
            };
        },
        quantity: function(product) {
            // Return the quantity in stock for a product
            if (product) { // product may be undefined, before it is loaded
                for (var i=0; i<$localStorage.cart.length; i++) {
                    if ($localStorage.cart[i].product.id == product.id) {
                        return $localStorage.cart[i].quantity;
                    };
                };
            };
            return 0;
        },
        total: function() {
            // Calculate the total amount of the cart
            var amount = 0;
            for (var i=0; i<$localStorage.cart.length; i++) {
                var cartline = $localStorage.cart[i];
                amount += cartline.quantity * parseFloat(cartline.product.net_price);
            }
            return amount;
        },
        count: function() {
            // Count the number of products in the cart
            var count = 0;
            for (var i=0; i<$localStorage.cart.length; i++) {
                var cartline = $localStorage.cart[i];
                // First, check and adjust the quantity
                if (!cartline.quantity) {
                    cartline.quantity = 1;
                } else if (cartline.quantity > cartline.product.stock && cartline.product.overstock_delay >= 0) {
                    // Reduce quantity to stock if overstock is not allowed
                    cartline.quantity = cartline.product.stock;
                };
                count += cartline.quantity;
            }
            return count;
        },
        reset: function() {
            // Empty the cart and go back to the index
            $localStorage.cart = [];
            $state.go('index');
        },
        empty: function() {
            // Empty the cart;
            $localStorage.cart = [];
        },
        list: function() {
            // Return the whole cart data
            return $localStorage.cart;
        },
        overstock: function() {
            // Is any product in the cart to be ordered on demand
            // (used for checkout)
            for (var i=0; i<$localStorage.cart.length; i++) {
                var cartline = $localStorage.cart[i];
                if (cartline.product.overstock_delay >= 0 && cartline.product.stock < cartline.quantity) {
                    // If the stock is not sufficient for a single "not
                    // overstock" product, the whole cart is marked as "not in
                    // stock"
                    return true;
                };
            };
            return false;
        },
        delay: function() {
            // Delay for the whole cart
            // (used for checkout and cart display)
            var delay = 0;
            for (var i=0; i<$localStorage.cart.length; i++) {
                var product = $localStorage.cart[i].product;
                if (product.stock < $localStorage.cart[i].quantity) {
                    if (product.overstock_delay >= 0) {
                        delay = Math.max(product.overstock_delay, delay);
                    } else {
                        delay = false;
                    }
                } else {
                    delay = Math.max(product.delay, delay);
                };
            };
            return delay;
        }
    }
})
.factory('orders', function($rootScope, $http, $timeout, user) {
    var orders;
    function get_orders() {
        $http.get('/api/order')
            .then(function(response) {
                orders = response.data;
            });
    };
    if (user.get()) {
        get_orders();
    };
    $rootScope.$on('event:auth-loginConfirmed', function(e, data) {
        // Timeout, just to be sure it is executed after the user data is loaded
        $timeout(function() {
            get_orders();
        }, 10);
    });
    return {
        count: function() {
            if (orders) {
                return orders.length;
            } else {
                return '';
            };
        },
        get: function() {
            return orders;
        },
        add: function(order) {
            orders.push(order);
        }
    }

})
.factory('title', function() {
    var title = '';
    return {
        set: function(newtitle) {
            title = newtitle;
        },
        get: function() {
            return title;
        }
    }
})
.run(function($timeout, $rootScope, $document, title) {
    $rootScope.$on('$stateChangeSuccess', function(event, toState) {
        if (toState.title) {
            // Without this timeout, the history is scrambled
            $timeout(function() {
                title.set(toState.title);
            }, 0);
        };
        $document.scrollTop(0,300);
    });
})
.directive('productsList', function() {
    return {
        restrict: 'E',
        scope: {
            products: '=products'
        },
        templateUrl: 'part/productslist'
    };
})
.controller('TitleCtrl', function($scope, title) {
    $scope.title = title;
})
.controller('UserCtrl', function($scope, user, savedCarts, orders) {
    $scope.user = user;
    $scope.saved_carts = savedCarts;
    $scope.orders = orders;
})
.controller('NewProductsCtrl', function($scope, newproducts) {
    $scope.newproducts = newproducts;
})
.controller('CategoriesListCtrl', function($scope, categories) {
    $scope.categories = categories;
})
.controller('DocsListCtrl', function($scope, docs) {
    $scope.docs = docs;
})
.controller('InfosListCtrl', function($scope, infos) {
    $scope.infos = infos;
})
.controller('SearchFormCtrl', function($scope, $state) {
    $scope.search = function() {
        $state.go('search', {'q': $scope.terms});
    }
})
<commit_msg>Fix a bug where the cart is not marked as "insufficient stock"<commit_after>/* Copyright 2015-2016 Sébastien Maccagnoni-Munch
 *
 * This file is part of AwesomeShop.
 *
 * AwesomeShop is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * AwesomeShop is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with AwesomeShop. If not, see <http://www.gnu.org/licenses/>.
 */
angular.module('awesomeshop', [
        // External modules
        'duScroll', 'ngAnimate', 'ngStorage', 'ui.bootstrap', 'ui.router',
        // Common awesomeshop modules
        'authentication', 'config', 'spinner',
        // Shop modules
        'shopPage', 'shopUser',
        'shopShop'
])
.config(function($locationProvider, $interpolateProvider, $urlRouterProvider, $urlMatcherFactoryProvider) {
    $locationProvider.html5Mode(true);
    $interpolateProvider.startSymbol('[[');
    $interpolateProvider.endSymbol(']]');
    $urlRouterProvider.otherwise('/');
    $urlMatcherFactoryProvider.strictMode(false);
})
.filter('trusthtml', function($sce) {
    return $sce.trustAsHtml;
})
.filter('htmlbr', function($sce) {
    return function(input) {
        if (input) {
            return $sce.trustAsHtml(input.replace(/\n/g, '
'));
        };
    };
})
.factory('translation', function($http) {
    var translations;
    $http.get('/messages')
        .then(function(response) {
            translations = response.data;
        });
    return function (message) {
        if (translations) {
            return translations[message] || message;
        } else {
            return message;
        };
    };
})
.filter('translate', function(translation) {
    return function(input) {
        return translation(input);
    }
})
.factory('countries', function($http) {
    var countries;
    $http.get('/api/country')
        .then(function(response) {
            countries = response.data;
        });
    return {
        get: function() {
            return countries;
        }
    };
})
.factory('newproducts', function($http) {
    var newproducts;
    $http.get('/api/newproducts')
        .then(function(response) {
            newproducts = response.data;
        });
    return {
        get: function() {
            return newproducts;
        },
        count: function() {
            if (newproducts) {
                return newproducts.length;
            } else {
                return 0;
            };
        }
    };
})
.factory('products', function($http, $q, $httpParamSerializer) {
    var catslugs = {},
        products = {};
    function get_product(productid, data, resolve, reject) {
        var prod;
        if (products[productid]) {
            prod = products[productid][data];
        };
        if (prod) {
            resolve(angular.copy(prod));
        } else {
            if (data) {
                params = {data: data};
            } else {
                params = {};
            }
            $http.get('/api/product/'+productid, {params: params})
                .then(function(response) {
                    var prod = response.data;
                    if (!products[prod.id]) {
                        products[prod.id] = {};
                    };
                    products[prod.id][data] = prod;
                    resolve(angular.copy(prod));
                }, reject);
        };
    };
    return {
        getid: function(productid, data, scope) {
            return $q(function(resolve, reject) {
                get_product(productid, data, resolve, reject);
            })
        },
        getcatslug: function(cat, slug, data) {
            var catslug = cat+'/'+slug;
            return $q(function(resolve, reject) {
                var productid = catslugs[catslug];
                if (productid) {
                    // This product is already known
                    get_product(productid, data, resolve, reject);
                } else {
                    // Download from the catslug
                    if (data) {
                        params = {data: data};
                    } else {
                        params = {};
                    }
                    $http.get('/api/product/catslug/'+catslug, {params: params})
                        .then(function(response) {
                            var prod = response.data;
                            if (!products[prod.id]) {
                                products[prod.id] = {};
                            };
                            products[prod.id][data] = prod;
                            catslugs[catslug] = prod.id;
                            get_product(prod.id, data, resolve, reject);
                        }, reject);
                };
            })
        }
    };
})
.factory('categories', function($rootScope, $http) {
    var categories,
        current_product_category;
    $http.get('/api/category', {params: {'flat':'true'}})
        .then(function(response) {
            categories = response.data;
        });
    $rootScope.$on('$stateChangeStart', function() {
        current_product_category = undefined;
    });
    $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams) {
        if (toState.name == 'product') {
            current_product_category = toParams.category;
        };
    });
    return {
        get: function() {
            return categories;
        },
        from_current_product() {
            return current_product_category;
        }
    };
})
.factory('docs', function($http) {
    var docs;
    $http.get('/api/page-doc')
        .then(function(response) {
            docs = response.data;
        });
    return {
        get: function() {
            return docs;
        }
    };
})
.factory('infos', function($http) {
    var infos;
    $http.get('/api/page-info')
        .then(function(response) {
            infos = response.data;
        });
    return {
        get: function() {
            return infos;
        }
    };
})
.factory('user', function($rootScope, $state, $http, $uibModal) {
    var user = undefined;
    $http.get('/api/userdata')
        .then(function(response) {
            user = response.data;
            if (response.data.auth) {
                $rootScope.$broadcast('event:auth-loginConfirmed', response.data);
            };
        });
    $rootScope.$on('event:auth-loginConfirmed', function(e, data) {
        user = data;
    });
    return {
        forcelogin: function() {
            $http.get('/api/forcelogin');
        },
        get: function() {
            return user;
        },
        set: function(data) {
            user = data;
        },
        logout: function() {
            $http.get('/api/logout')
                .then(function(response) {
                    user = response.data;
                    $state.go('index');
                });
        },
        resend_confirmation: function() {
            $http.get('/api/register/resend');
        },
        setlang: function(lang) {
            $http.put('/api/setlang', {'lang': lang})
                .then(function() {
                    window.location.reload();
                })
        }
    }
})
.factory('savedCarts', function($rootScope, $timeout, $http, cart, user) {
    var carts;
    function get_saved_carts() {
        $http.get('/api/cart')
            .then(function(response) {
                carts = response.data;
            });
    };
    if (user.get()) {
        get_saved_carts();
    };
    $rootScope.$on('event:auth-loginConfirmed', function(e, data) {
        // Timeout, just to be sure it is executed after the user data is loaded
        $timeout(function() {
            get_saved_carts();
        }, 10);
    });
    return {
        get: function() {
            return carts;
        },
        add: function(cart) {
            carts.push(cart);
        },
        count: function() {
            if (carts) {
                return carts.length;
            } else {
                return '';
            };
        },
        remove: function(index) {
            $http.delete('/api/cart/'+carts[index].id)
                .then(function() {
                    carts.splice(index, 1);
                })
        }
    };
})
.factory('cart', function($localStorage, $http, $state, products) {
    if ($localStorage.cart) {
        // Ask the server to adjust the cart (availability and price)
        $http.post('/api/cart/verify', $localStorage.cart)
            .then(function(response) {
                $localStorage.cart = response.data;
            });
    } else {
        $localStorage.cart = [];
    };
    return {
        add: function(productid, data, quantity) {
            // Add a product to the cart
            products.getid(productid, data)
                .then(function(prod) {
                    for (var i=0; i<$localStorage.cart.length; i++) {
                        var cartline = $localStorage.cart[i];
                        if (cartline.product.id == prod.id &&
                            cartline.data == data) {
                                cartline.quantity += quantity;
                                return;
                        }
                    };
                    // Product was not found, adding it
                    $localStorage.cart.push({
                        product: prod,
                        data: data,
                        quantity: quantity
                    })
                })
        },
        remove: function(productid, data) {
            // Completely remove the product from the cart
            for (var i=0; i<$localStorage.cart.length; i++) {
                if ($localStorage.cart[i].product.id == productid &&
                    $localStorage.cart[i].data == data) {
                        $localStorage.cart.splice(i, 1);
                        break;
                };
            };
        },
        load: function(cart, do_not_verify) {
            // Load a stored cart in the live cart
            // do_not_verify = False, ask the server to confirm the quantity in cart
            if (do_not_verify) {
                $localStorage.cart = cart;
            } else {
                $http.post('/api/cart/verify', cart)
                    .then(function(response) {
                        $localStorage.cart = response.data;
                    });
            };
        },
        quantity: function(product) {
            // Return the quantity in stock for a product
            if (product) { // product may be undefined, before it is loaded
                for (var i=0; i<$localStorage.cart.length; i++) {
                    if ($localStorage.cart[i].product.id == product.id) {
                        return $localStorage.cart[i].quantity;
                    };
                };
            };
            return 0;
        },
        total: function() {
            // Calculate the total amount of the cart
            var amount = 0;
            for (var i=0; i<$localStorage.cart.length; i++) {
                var cartline = $localStorage.cart[i];
                amount += cartline.quantity * parseFloat(cartline.product.net_price);
            }
            return amount;
        },
        count: function() {
            // Count the number of products in the cart
            var count = 0;
            for (var i=0; i<$localStorage.cart.length; i++) {
                var cartline = $localStorage.cart[i];
                // First, check and adjust the quantity
                if (!cartline.quantity) {
                    cartline.quantity = 1;
                } else if (cartline.quantity > cartline.product.stock && cartline.product.overstock_delay >= 0) {
                    // Reduce quantity to stock if overstock is not allowed
                    cartline.quantity = cartline.product.stock;
                };
                count += cartline.quantity;
            }
            return count;
        },
        reset: function() {
            // Empty the cart and go back to the index
            $localStorage.cart = [];
            $state.go('index');
        },
        empty: function() {
            // Empty the cart;
            $localStorage.cart = [];
        },
        list: function() {
            // Return the whole cart data
            return $localStorage.cart;
        },
        overstock: function() {
            // Is any product in the cart to be ordered on demand
            // (used for checkout)
            for (var i=0; i<$localStorage.cart.length; i++) {
                var cartline = $localStorage.cart[i];
                if (cartline.product.overstock_delay >= 0 && cartline.product.stock < cartline.quantity) {
                    // If the stock is not sufficient for a single "not
                    // overstock" product, the whole cart is marked as "not in
                    // stock"
                    return true;
                };
            };
            return false;
        },
        delay: function() {
            // Delay for the whole cart
            // (used for checkout and cart display)
            var delay = 0;
            for (var i=0; i<$localStorage.cart.length; i++) {
                var product = $localStorage.cart[i].product;
                if (product.stock < $localStorage.cart[i].quantity) {
                    if (product.overstock_delay >= 0 && delay !== false) {
                        delay = Math.max(product.overstock_delay, delay);
                    } else {
                        delay = false;
                    }
                } else if (delay !== false) {
                    delay = Math.max(product.delay, delay);
                };
            };
            return delay;
        }
    }
})
.factory('orders', function($rootScope, $http, $timeout, user) {
    var orders;
    function get_orders() {
        $http.get('/api/order')
            .then(function(response) {
                orders = response.data;
            });
    };
    if (user.get()) {
        get_orders();
    };
    $rootScope.$on('event:auth-loginConfirmed', function(e, data) {
        // Timeout, just to be sure it is executed after the user data is loaded
        $timeout(function() {
            get_orders();
        }, 10);
    });
    return {
        count: function() {
            if (orders) {
                return orders.length;
            } else {
                return '';
            };
        },
        get: function() {
            return orders;
        },
        add: function(order) {
            orders.push(order);
        }
    }

})
.factory('title', function() {
    var title = '';
    return {
        set: function(newtitle) {
            title = newtitle;
        },
        get: function() {
            return title;
        }
    }
})
.run(function($timeout, $rootScope, $document, title) {
    $rootScope.$on('$stateChangeSuccess', function(event, toState) {
        if (toState.title) {
            // Without this timeout, the history is scrambled
            $timeout(function() {
                title.set(toState.title);
            }, 0);
        };
        $document.scrollTop(0,300);
    });
})
.directive('productsList', function() {
    return {
        restrict: 'E',
        scope: {
            products: '=products'
        },
        templateUrl: 'part/productslist'
    };
})
.controller('TitleCtrl', function($scope, title) {
    $scope.title = title;
})
.controller('UserCtrl', function($scope, user, savedCarts, orders) {
    $scope.user = user;
    $scope.saved_carts = savedCarts;
    $scope.orders = orders;
})
.controller('NewProductsCtrl', function($scope, newproducts) {
    $scope.newproducts = newproducts;
})
.controller('CategoriesListCtrl', function($scope, categories) {
    $scope.categories = categories;
})
.controller('DocsListCtrl', function($scope, docs) {
    $scope.docs = docs;
})
.controller('InfosListCtrl', function($scope, infos) {
    $scope.infos = infos;
})
.controller('SearchFormCtrl', function($scope, $state) {
    $scope.search = function() {
        $state.go('search', {'q': $scope.terms});
    }
})
<|endoftext|>


<commit_before>HTMLWidgets.widget({

  name: 'd3tree',

  type: 'output',

  initialize: function(el, width, height) {

    return {

    }

  },

  renderValue: function(el, x, instance) {

    // thanks Bill White for his treemap code on which this is based
    //    http://www.billdwhite.com/wordpress/2012/12/16/d3-treemap-with-title-headers/

    // set this as constant false instead of trying to detect browser type
    //   but leave in case we need to revert back to detecting IE
    var isIE = false;

    var chartWidth = el.getBoundingClientRect().width;
    var chartHeight = el.getBoundingClientRect().height;
    var xscale = d3.scale.linear().range([0, chartWidth]);
    var yscale = d3.scale.linear().range([0, chartHeight]);
    var color = d3.scale.category10();
    var headerHeight = 20;
    var headerColor = "#555555";
    var transitionDuration = 500;
    var root;
    var node;

    var treemap = d3.layout.treemap()
        .round(false)
        .size([chartWidth, chartHeight])
        .sticky(true)
        .value(function(d) {
            return d.size;
        });

    var svg = d3.select(el)
        .append("svg:svg")
        .attr("width", chartWidth)
        .attr("height", chartHeight);

    var chart = svg.append("svg:g");

    var defs = svg.append("defs");

    var filter = defs.append("svg:filter")
        .attr("id", "outerDropShadow")
        .attr("x", "-20%")
        .attr("y", "-20%")
        .attr("width", "140%")
        .attr("height", "140%");

    filter.append("svg:feOffset")
        .attr("result", "offOut")
        .attr("in", "SourceGraphic")
        .attr("dx", "1")
        .attr("dy", "1");

    filter.append("svg:feColorMatrix")
        .attr("result", "matrixOut")
        .attr("in", "offOut")
        .attr("type", "matrix")
        .attr("values", "1 0 0 0 0 0 0.1 0 0 0 0 0 0.1 0 0 0 0 0 .5 0");

    filter.append("svg:feGaussianBlur")
        .attr("result", "blurOut")
        .attr("in", "matrixOut")
        .attr("stdDeviation", "3");

    filter.append("svg:feBlend")
        .attr("in", "SourceGraphic")
        .attr("in2", "blurOut")
        .attr("mode", "normal");

    drawTree( x.data, x.options.id, x.options.celltext );

    function drawTree( data, id, celltext ) {
        id ? id : "id";
        celltext ? celltext : "name";
        node = root = data;
        var nodes = treemap.nodes(root);

        var children = nodes.filter(function(d) {
            return !d.children;
        });
        var parents = nodes.filter(function(d) {
            return d.children;
        });

        // create parent cells
        var parentCells = chart.selectAll("g.cell.parent")
            .data(parents, function(d) {
                return "p-" + d[id];
            });
        var parentEnterTransition = parentCells.enter()
            .append("g")
            .attr("class", "cell parent")
            .on("click", function(d) {
                zoom(d);
            })
            .append("svg")
            .attr("class", "clip")
            .attr("width", function(d) {
                return Math.max(0.01, d.dx);
            })
            .attr("height", headerHeight);
        parentEnterTransition.append("rect")
            .attr("width", function(d) {
                return Math.max(0.01, d.dx);
            })
            .attr("height", headerHeight)
            .style("fill", headerColor);
        parentEnterTransition.append('text')
            .attr("class", "label")
            .attr("transform", "translate(3, 13)")
            .attr("width", function(d) {
                return Math.max(0.01, d.dx);
            })
            .attr("height", headerHeight)
            .text(function(d) {
                return d[celltext];
            });
        // update transition
        var parentUpdateTransition = parentCells.transition().duration(transitionDuration);
        parentUpdateTransition.select(".cell")
            .attr("transform", function(d) {
                return "translate(" + d.dx + "," + d.y + ")";
            });
        parentUpdateTransition.select("rect")
            .attr("width", function(d) {
                return Math.max(0.01, d.dx);
            })
            .attr("height", headerHeight)
            .style("fill", headerColor);
        parentUpdateTransition.select(".label")
            .attr("transform", "translate(3, 13)")
            .attr("width", function(d) {
                return Math.max(0.01, d.dx);
            })
            .attr("height", headerHeight)
            .text(function(d) {
                return d[celltext];
            });
        // remove transition
        parentCells.exit()
            .remove();

        // create children cells
        var childrenCells = chart.selectAll("g.cell.child")
            .data(children, function(d) {
                return "c-" + d[id];
            });
        // enter transition
        var childEnterTransition = childrenCells.enter()
            .append("g")
            .attr("class", "cell child")
            .on("click", function(d) {
                zoom(node === d.parent ? root : d.parent);
            })
            .on("mouseover", function() {
                this.parentNode.appendChild(this); // workaround for bringing elements to the front (ie z-index)
                d3.select(this)
                    .attr("filter", "url(#outerDropShadow)")
                    .select(".background")
                    .style("stroke", "#000000");
            })
            .on("mouseout", function() {
              d3.select(this)
                    .attr("filter", "")
                    .select(".background")
                    .style("stroke", "#FFFFFF");
            })
            .append("svg")
            .attr("class", "clip")
        childEnterTransition.append("rect")
            .classed("background", true)
            .style("fill", function(d) {
                return d.color ? d.color :  color(d.parent[id]);
            });
        childEnterTransition.append('text')
            .attr("class", "label")
            .attr('x', function(d) {
                return d.dx / 2;
            })
            .attr('y', function(d) {
                return d.dy / 2;
            })
            .attr("dy", ".35em")
            .attr("text-anchor", "middle")
            .style("display", "none")
            .text(function(d) {
                return d[celltext];
            });
        // update transition
        var childUpdateTransition = childrenCells.transition().duration(transitionDuration);
        childUpdateTransition.select(".cell")
            .attr("transform", function(d) {
                return "translate(" + d.x + "," + d.y + ")";
            });
        childUpdateTransition.select("rect")
            .attr("width", function(d) {
                return Math.max(0.01, d.dx);
            })
            .attr("height", function(d) {
                return d.dy;
            })
            .style("fill", function(d) {
                return d.color ? d.color : color(d.parent[id]);
            });
        childUpdateTransition.select(".label")
            .attr('x', function(d) {
                return d.dx / 2;
            })
            .attr('y', function(d) {
                return d.dy / 2;
            })
            .attr("dy", ".35em")
            .attr("text-anchor", "middle")
            .style("display", "none")
            .text(function(d) {
                return d[celltext];
            });

        // exit transition
        childrenCells.exit()
            .remove();

        d3.select("select").on("change", function() {
            console.log("select zoom(node)");
            treemap.value(this.value == "size" ? size : count)
                .nodes(root);
            zoom(node);
        });

        zoom(node);
    };

    function size(d) {
        return d.size;
    }

    function count(d) {
        return 1;
    }

    //and another one
    function textHeight(d) {
        var ky = chartHeight / d.dy;
        yscale.domain([d.y, d.y + d.dy]);
        return (ky * d.dy) / headerHeight;
    }

    function getRGBComponents(color) {
        var r = color.substring(1, 3);
        var g = color.substring(3, 5);
        var b = color.substring(5, 7);
        return {
            R: parseInt(r, 16),
            G: parseInt(g, 16),
            B: parseInt(b, 16)
        };
    }

    function idealTextColor(bgColor) {
        var nThreshold = 105;
        var components = getRGBComponents(bgColor);
        var bgDelta = (components.R * 0.299) + (components.G * 0.587) + (components.B * 0.114);
        return ((255 - bgDelta) < nThreshold) ? "#000000" : "#ffffff";
    }

    function zoom(d) {
        treemap
            .padding([headerHeight / (chartHeight / d.dy), 0, 0, 0])
            .nodes(d);

        // moving the next two lines above treemap layout messes up padding of zoom result
        var kx = chartWidth / d.dx;
        var ky = chartHeight / d.dy;
        var level = d;

        xscale.domain([d.x, d.x + d.dx]);
        yscale.domain([d.y, d.y + d.dy]);

        if (node != level) {
            chart.selectAll(".cell.child .label")
                .style("display", "none");
        }

        var zoomTransition = chart.selectAll("g.cell").transition().duration(transitionDuration)
            .attr("transform", function(d) {
                return "translate(" + xscale(d.x) + "," + yscale(d.y) + ")";
            })
            .each("start", function() {
                d3.select(this).select("label")
                    .style("display", "none");
            })
            .each("end", function(d, i) {
                if (!i && (level !== root)) {
                    chart.selectAll(".cell.child")
                        .filter(function(d) {
                            return d.parent === node; // only get the children for selected group
                        })
                        .select(".label")
                        .style("display", "")
                        .style("fill", function(d) {
                            return idealTextColor(d.color ? d.color : color(d.parent[id]));
                        });
                }
            });

        zoomTransition.select(".clip")
            .attr("width", function(d) {
                return Math.max(0.01, (kx * d.dx));
            })
            .attr("height", function(d) {
                return d.children ? headerHeight : Math.max(0.01, (ky * d.dy));
            });

        zoomTransition.select(".label")
            .attr("width", function(d) {
                return Math.max(0.01, (kx * d.dx));
            })
            .attr("height", function(d) {
                return d.children ? headerHeight : Math.max(0.01, (ky * d.dy));
            })
        .text(function(d) {
                return d[celltext];
            });

        zoomTransition.select(".child .label")
            .attr("x", function(d) {
                return kx * d.dx / 2;
            })
            .attr("y", function(d) {
                return ky * d.dy / 2;
            });

        zoomTransition.select("rect")
            .attr("width", function(d) {
                return Math.max(0.01, (kx * d.dx));
            })
            .attr("height", function(d) {
                return d.children ? headerHeight : Math.max(0.01, (ky * d.dy));
            })
            .style("fill", function(d) {
                return d.children ? headerColor : ( d.color ? d.color : color(d.parent[id]) );
            });

        node = d;

        if (d3.event) {
            d3.event.stopPropagation();
        }
    }

  },

  resize: function(el, width, height, instance) {

  }

});
<commit_msg>get celltext working correctly<commit_after>HTMLWidgets.widget({

  name: 'd3tree',

  type: 'output',

  initialize: function(el, width, height) {

    return {

    }

  },

  renderValue: function(el, x, instance) {

    // thanks Bill White for his treemap code on which this is based
    //    http://www.billdwhite.com/wordpress/2012/12/16/d3-treemap-with-title-headers/

    // set this as constant false instead of trying to detect browser type
    //   but leave in case we need to revert back to detecting IE
    var isIE = false;

    var chartWidth = el.getBoundingClientRect().width;
    var chartHeight = el.getBoundingClientRect().height;
    var xscale = d3.scale.linear().range([0, chartWidth]);
    var yscale = d3.scale.linear().range([0, chartHeight]);
    var color = d3.scale.category10();
    var headerHeight = 20;
    var headerColor = "#555555";
    var transitionDuration = 500;
    var root;
    var node;

    var treemap = d3.layout.treemap()
        .round(false)
        .size([chartWidth, chartHeight])
        .sticky(true)
        .value(function(d) {
            return d.size;
        });

    var svg = d3.select(el)
        .append("svg:svg")
        .attr("width", chartWidth)
        .attr("height", chartHeight);

    var chart = svg.append("svg:g");

    var defs = svg.append("defs");

    var filter = defs.append("svg:filter")
        .attr("id", "outerDropShadow")
        .attr("x", "-20%")
        .attr("y", "-20%")
        .attr("width", "140%")
        .attr("height", "140%");

    filter.append("svg:feOffset")
        .attr("result", "offOut")
        .attr("in", "SourceGraphic")
        .attr("dx", "1")
        .attr("dy", "1");

    filter.append("svg:feColorMatrix")
        .attr("result", "matrixOut")
        .attr("in", "offOut")
        .attr("type", "matrix")
        .attr("values", "1 0 0 0 0 0 0.1 0 0 0 0 0 0.1 0 0 0 0 0 .5 0");

    filter.append("svg:feGaussianBlur")
        .attr("result", "blurOut")
        .attr("in", "matrixOut")
        .attr("stdDeviation", "3");

    filter.append("svg:feBlend")
        .attr("in", "SourceGraphic")
        .attr("in2", "blurOut")
        .attr("mode", "normal");

    drawTree( x.data, x.options.id, x.options.celltext );

    function drawTree( data, id, celltext ) {
        id ? id : "id";
        celltext ? celltext : "name";
        node = root = data;
        var nodes = treemap.nodes(root);

        var children = nodes.filter(function(d) {
            return !d.children;
        });
        var parents = nodes.filter(function(d) {
            return d.children;
        });

        // create parent cells
        var parentCells = chart.selectAll("g.cell.parent")
            .data(parents, function(d) {
                return "p-" + d[id];
            });
        var parentEnterTransition = parentCells.enter()
            .append("g")
            .attr("class", "cell parent")
            .on("click", function(d) {
                zoom(d, celltext);
            })
            .append("svg")
            .attr("class", "clip")
            .attr("width", function(d) {
                return Math.max(0.01, d.dx);
            })
            .attr("height", headerHeight);
        parentEnterTransition.append("rect")
            .attr("width", function(d) {
                return Math.max(0.01, d.dx);
            })
            .attr("height", headerHeight)
            .style("fill", headerColor);
        parentEnterTransition.append('text')
            .attr("class", "label")
            .attr("transform", "translate(3, 13)")
            .attr("width", function(d) {
                return Math.max(0.01, d.dx);
            })
            .attr("height", headerHeight)
            .text(function(d) {
                return d[celltext];
            });
        // update transition
        var parentUpdateTransition = parentCells.transition().duration(transitionDuration);
        parentUpdateTransition.select(".cell")
            .attr("transform", function(d) {
                return "translate(" + d.dx + "," + d.y + ")";
            });
        parentUpdateTransition.select("rect")
            .attr("width", function(d) {
                return Math.max(0.01, d.dx);
            })
            .attr("height", headerHeight)
            .style("fill", headerColor);
        parentUpdateTransition.select(".label")
            .attr("transform", "translate(3, 13)")
            .attr("width", function(d) {
                return Math.max(0.01, d.dx);
            })
            .attr("height", headerHeight)
            .text(function(d) {
                return d[celltext];
            });
        // remove transition
        parentCells.exit()
            .remove();

        // create children cells
        var childrenCells = chart.selectAll("g.cell.child")
            .data(children, function(d) {
                return "c-" + d[id];
            });
        // enter transition
        var childEnterTransition = childrenCells.enter()
            .append("g")
            .attr("class", "cell child")
            .on("click", function(d) {
                zoom(node === d.parent ? root : d.parent, celltext);
            })
            .on("mouseover", function() {
                this.parentNode.appendChild(this); // workaround for bringing elements to the front (ie z-index)
                d3.select(this)
                    .attr("filter", "url(#outerDropShadow)")
                    .select(".background")
                    .style("stroke", "#000000");
            })
            .on("mouseout", function() {
              d3.select(this)
                    .attr("filter", "")
                    .select(".background")
                    .style("stroke", "#FFFFFF");
            })
            .append("svg")
            .attr("class", "clip")
        childEnterTransition.append("rect")
            .classed("background", true)
            .style("fill", function(d) {
                return d.color ? d.color :  color(d.parent[id]);
            });
        childEnterTransition.append('text')
            .attr("class", "label")
            .attr('x', function(d) {
                return d.dx / 2;
            })
            .attr('y', function(d) {
                return d.dy / 2;
            })
            .attr("dy", ".35em")
            .attr("text-anchor", "middle")
            .style("display", "none")
            .text(function(d) {
                return d[celltext];
            });
        // update transition
        var childUpdateTransition = childrenCells.transition().duration(transitionDuration);
        childUpdateTransition.select(".cell")
            .attr("transform", function(d) {
                return "translate(" + d.x + "," + d.y + ")";
            });
        childUpdateTransition.select("rect")
            .attr("width", function(d) {
                return Math.max(0.01, d.dx);
            })
            .attr("height", function(d) {
                return d.dy;
            })
            .style("fill", function(d) {
                return d.color ? d.color : color(d.parent[id]);
            });
        childUpdateTransition.select(".label")
            .attr('x', function(d) {
                return d.dx / 2;
            })
            .attr('y', function(d) {
                return d.dy / 2;
            })
            .attr("dy", ".35em")
            .attr("text-anchor", "middle")
            .style("display", "none")
            .text(function(d) {
                return d[celltext];
            });

        // exit transition
        childrenCells.exit()
            .remove();

        d3.select("select").on("change", function() {
            console.log("select zoom(node)");
            treemap.value(this.value == "size" ? size : count)
                .nodes(root);
            zoom(node, celltext);
        });

        zoom(node,celltext);
    };

    function size(d) {
        return d.size;
    }

    function count(d) {
        return 1;
    }

    //and another one
    function textHeight(d) {
        var ky = chartHeight / d.dy;
        yscale.domain([d.y, d.y + d.dy]);
        return (ky * d.dy) / headerHeight;
    }

    function getRGBComponents(color) {
        var r = color.substring(1, 3);
        var g = color.substring(3, 5);
        var b = color.substring(5, 7);
        return {
            R: parseInt(r, 16),
            G: parseInt(g, 16),
            B: parseInt(b, 16)
        };
    }

    function idealTextColor(bgColor) {
        var nThreshold = 105;
        var components = getRGBComponents(bgColor);
        var bgDelta = (components.R * 0.299) + (components.G * 0.587) + (components.B * 0.114);
        return ((255 - bgDelta) < nThreshold) ? "#000000" : "#ffffff";
    }

    function zoom(d, celltext) {
        celltext ? celltext : "name";
        treemap
            .padding([headerHeight / (chartHeight / d.dy), 0, 0, 0])
            .nodes(d);

        // moving the next two lines above treemap layout messes up padding of zoom result
        var kx = chartWidth / d.dx;
        var ky = chartHeight / d.dy;
        var level = d;

        xscale.domain([d.x, d.x + d.dx]);
        yscale.domain([d.y, d.y + d.dy]);

        if (node != level) {
            chart.selectAll(".cell.child .label")
                .style("display", "none");
        }

        var zoomTransition = chart.selectAll("g.cell").transition().duration(transitionDuration)
            .attr("transform", function(d) {
                return "translate(" + xscale(d.x) + "," + yscale(d.y) + ")";
            })
            .each("start", function() {
                d3.select(this).select("label")
                    .style("display", "none");
            })
            .each("end", function(d, i) {
                if (!i && (level !== root)) {
                    chart.selectAll(".cell.child")
                        .filter(function(d) {
                            return d.parent === node; // only get the children for selected group
                        })
                        .select(".label")
                        .style("display", "")
                        .style("fill", function(d) {
                            return idealTextColor(d.color ? d.color : color(d.parent[id]));
                        });
                }
            });

        zoomTransition.select(".clip")
            .attr("width", function(d) {
                return Math.max(0.01, (kx * d.dx));
            })
            .attr("height", function(d) {
                return d.children ? headerHeight : Math.max(0.01, (ky * d.dy));
            });

        zoomTransition.select(".label")
            .attr("width", function(d) {
                return Math.max(0.01, (kx * d.dx));
            })
            .attr("height", function(d) {
                return d.children ? headerHeight : Math.max(0.01, (ky * d.dy));
            })
        .text(function(d) {
                return d[celltext];
            });

        zoomTransition.select(".child .label")
            .attr("x", function(d) {
                return kx * d.dx / 2;
            })
            .attr("y", function(d) {
                return ky * d.dy / 2;
            });

        zoomTransition.select("rect")
            .attr("width", function(d) {
                return Math.max(0.01, (kx * d.dx));
            })
            .attr("height", function(d) {
                return d.children ? headerHeight : Math.max(0.01, (ky * d.dy));
            })
            .style("fill", function(d) {
                return d.children ? headerColor : ( d.color ? d.color : color(d.parent[id]) );
            });

        node = d;

        if (d3.event) {
            d3.event.stopPropagation();
        }
    }

  },

  resize: function(el, width, height, instance) {

  }

});
<|endoftext|>


<commit_before>/*************************************************
 * Copyright (c) 2015 Ansible, Inc.
 *
 * All Rights Reserved
 *************************************************/

/**
 * @ngdoc function
 * @name controllers.function:Users
 * @description This controller's the Users page
 */

import { N_ } from "../i18n";

const user_type_options = [
    { type: 'normal', label: N_('Normal User') },
    { type: 'system_auditor', label: N_('System Auditor') },
    { type: 'system_administrator', label: N_('System Administrator') },
];

function user_type_sync($scope) {
    return (type_option) => {
        $scope.is_superuser = false;
        $scope.is_system_auditor = false;
        switch (type_option.type) {
            case 'system_administrator':
                $scope.is_superuser = true;
                break;
            case 'system_auditor':
                $scope.is_system_auditor = true;
                break;
        }
    };
}

export function UsersList($scope, $rootScope, $stateParams,
    Rest, Alert, UserList, Prompt, ClearScope, ProcessErrors, GetBasePath,
    Wait, $state, $filter, rbacUiControlService, Dataset, i18n) {

    for (var i = 0; i < user_type_options.length; i++) {
        user_type_options[i].label = i18n._(user_type_options[i].label);
    }

    ClearScope();

    var list = UserList,
        defaultUrl = GetBasePath('users');

    init();

    function init() {
        $scope.canAdd = false;

        rbacUiControlService.canAdd('users')
            .then(function(canAdd) {
                $scope.canAdd = canAdd;
            });

        // search init
        $scope.list = list;
        $scope[`${list.iterator}_dataset`] = Dataset.data;
        $scope[list.name] = $scope[`${list.iterator}_dataset`].results;

        $rootScope.flashMessage = null;
        $scope.selected = [];
    }

    $scope.addUser = function() {
        $state.go('users.add');
    };

    $scope.editUser = function(id) {
        $state.go('users.edit', { user_id: id });
    };

    $scope.deleteUser = function(id, name) {

        var action = function() {
            $('#prompt-modal').modal('hide');
            Wait('start');
            var url = defaultUrl + id + '/';
            Rest.setUrl(url);
            Rest.destroy()
                .success(function() {
                    if (parseInt($state.params.user_id) === id) {
                        $state.go('^', null, { reload: true });
                    } else {
                        $state.go('.', null, { reload: true });
                    }
                })
                .error(function(data, status) {
                    ProcessErrors($scope, data, status, null, {
                        hdr: i18n._('Error!'),
                        msg: i18n.sprintf(i18n._('Call to %s failed. DELETE returned status: '), url) + status
                    });
                });
        };

        Prompt({
            hdr: i18n._('Delete'),
            body: '
' + i18n._('Are you sure you want to delete the user below?') + '

' + $filter('sanitize')(name) + '
',
            action: action,
            actionText: i18n._('DELETE')
        });
    };
}

UsersList.$inject = ['$scope', '$rootScope', '$stateParams',
    'Rest', 'Alert', 'UserList', 'Prompt', 'ClearScope', 'ProcessErrors', 'GetBasePath',
    'Wait', '$state', '$filter', 'rbacUiControlService', 'Dataset', 'i18n'
];

export function UsersAdd($scope, $rootScope, $stateParams, UserForm,
    GenerateForm, Rest, Alert, ProcessErrors, ReturnToCaller, ClearScope,
    GetBasePath, ResetForm, Wait, CreateSelect2, $state, $location, i18n) {

    ClearScope();

    var defaultUrl = GetBasePath('organizations'),
        form = UserForm;

    init();

    function init() {
        // apply form definition's default field values
        GenerateForm.applyDefaults(form, $scope);

        $scope.ldap_user = false;
        $scope.not_ldap_user = !$scope.ldap_user;
        $scope.ldap_dn = null;
        $scope.socialAuthUser = false;
        $scope.external_account = null;

        Rest.setUrl(GetBasePath('users'));
        Rest.options()
            .success(function(data) {
                if (!data.actions.POST) {
                    $state.go("^");
                    Alert(i18n._('Permission Error'), i18n._('You do not have permission to add a user.'), 'alert-info');
                }
            });

        $scope.user_type_options = user_type_options;
        $scope.user_type = user_type_options[0];
        $scope.$watch('user_type', user_type_sync($scope));
        CreateSelect2({
            element: '#user_user_type',
            multiple: false
        });
    }

    // Save
    $scope.formSave = function() {
        var fld, data = {};
        if ($scope[form.name + '_form'].$valid) {
            if ($scope.organization !== undefined && $scope.organization !== null && $scope.organization !== '') {
                Rest.setUrl(defaultUrl + $scope.organization + '/users/');
                for (fld in form.fields) {
                    if (form.fields[fld].realName) {
                        data[form.fields[fld].realName] = $scope[fld];
                    } else {
                        data[fld] = $scope[fld];
                    }
                }
                data.is_superuser = $scope.is_superuser;
                data.is_system_auditor = $scope.is_system_auditor;
                Wait('start');
                Rest.post(data)
                    .success(function(data) {
                        var base = $location.path().replace(/^\//, '').split('/')[0];
                        if (base === 'users') {
                            $rootScope.flashMessage = i18n._('New user successfully created!');
                            $rootScope.$broadcast("EditIndicatorChange", "users", data.id);
                            $state.go('users.edit', { user_id: data.id }, { reload: true });
                        } else {
                            ReturnToCaller(1);
                        }
                    })
                    .error(function(data, status) {
                        ProcessErrors($scope, data, status, form, { hdr: i18n._('Error!'), msg: i18n._('Failed to add new user. POST returned status: ') + status });
                    });
            } else {
                $scope.organization_name_api_error = i18n._('A value is required');
            }
        }
    };

    $scope.formCancel = function() {
        $state.go('users');
    };

    // Password change
    $scope.clearPWConfirm = function(fld) {
        // If password value changes, make sure password_confirm must be re-entered
        $scope[fld] = '';
        $scope[form.name + '_form'][fld].$setValidity('awpassmatch', false);
    };
}

UsersAdd.$inject = ['$scope', '$rootScope', '$stateParams', 'UserForm', 'GenerateForm',
    'Rest', 'Alert', 'ProcessErrors', 'ReturnToCaller', 'ClearScope', 'GetBasePath',
    'ResetForm', 'Wait', 'CreateSelect2', '$state', '$location', 'i18n'
];

export function UsersEdit($scope, $rootScope, $location,
    $stateParams, UserForm, Rest, ProcessErrors,
    ClearScope, GetBasePath, ResetForm, Wait, CreateSelect2, $state, i18n) {

    for (var i = 0; i < user_type_options.length; i++) {
        user_type_options[i].label = i18n._(user_type_options[i].label);
    }
    ClearScope();

    var form = UserForm,
        master = {},
        id = $stateParams.user_id,
        defaultUrl = GetBasePath('users') + id;

    init();

    function init() {
        $scope.user_type_options = user_type_options;
        $scope.user_type = user_type_options[0];
        $scope.$watch('user_type', user_type_sync($scope));
        Rest.setUrl(defaultUrl);
        Wait('start');
        Rest.get(defaultUrl).success(function(data) {
                $scope.user_id = id;
                $scope.ldap_user = (data.ldap_dn !== null && data.ldap_dn !== undefined && data.ldap_dn !== '') ? true : false;
                $scope.not_ldap_user = !$scope.ldap_user;
                master.ldap_user = $scope.ldap_user;
                $scope.socialAuthUser = (data.auth.length > 0) ? true : false;
                $scope.external_account = data.external_account;

                $scope.user_type = $scope.user_type_options[0];
                $scope.is_system_auditor = false;
                $scope.is_superuser = false;
                if (data.is_system_auditor) {
                    $scope.user_type = $scope.user_type_options[1];
                    $scope.is_system_auditor = true;
                }
                if (data.is_superuser) {
                    $scope.user_type = $scope.user_type_options[2];
                    $scope.is_superuser = true;
                }

                $scope.user_obj = data;

                CreateSelect2({
                    element: '#user_user_type',
                    multiple: false
                });

                $scope.$watch('user_obj.summary_fields.user_capabilities.edit', function(val) {
                    if (val === false) {
                        $scope.canAdd = false;
                    }
                });

                setScopeFields(data);
                Wait('stop');
            })
            .error(function(data, status) {
                ProcessErrors($scope, data, status, null, {
                    hdr: i18n._('Error!'),
                    msg: i18n.sprintf(i18n._('Failed to retrieve user: %s. GET status: '), $stateParams.id) + status
                });
            });
    }

    function setScopeFields(data) {
        _(data)
            .pick(function(value, key) {
                return form.fields.hasOwnProperty(key) === true;
            })
            .forEach(function(value, key) {
                $scope[key] = value;
            })
            .value();
        return;
    }

    $scope.convertApiUrl = function(str) {
        if (str) {
            return str.replace("api/v1", "#");
        } else {
            return null;
        }
    };

    // prepares a data payload for a PUT request to the API
    var processNewData = function(fields) {
        var data = {};
        _.forEach(fields, function(value, key) {
            if ($scope[key] !== '' && $scope[key] !== null && $scope[key] !== undefined) {
                data[key] = $scope[key];
            }
        });
        data.is_superuser = $scope.is_superuser;
        data.is_system_auditor = $scope.is_system_auditor;
        return data;
    };

    $scope.formCancel = function() {
        $state.go('users', null, { reload: true });
    };

    $scope.formSave = function() {
        $rootScope.flashMessage = null;
        if ($scope[form.name + '_form'].$valid) {
            Rest.setUrl(defaultUrl + '/');
            var data = processNewData(form.fields);
            Rest.put(data).success(function() {
                    $state.go($state.current, null, { reload: true });
                })
                .error(function(data, status) {
                    ProcessErrors($scope, data, status, null, {
                        hdr: i18n._('Error!'),
                        msg: i18n.sprintf(i18n._('Failed to retrieve user: %s. GET status: '), $stateParams.id) + status
                    });
                });
        }
    };

    $scope.clearPWConfirm = function(fld) {
        // If password value changes, make sure password_confirm must be re-entered
        $scope[fld] = '';
        $scope[form.name + '_form'][fld].$setValidity('awpassmatch', false);
        $rootScope.flashMessage = null;
    };
}

UsersEdit.$inject = ['$scope', '$rootScope', '$location',
    '$stateParams', 'UserForm', 'Rest', 'ProcessErrors', 'ClearScope', 'GetBasePath',
    'ResetForm', 'Wait', 'CreateSelect2', '$state', 'i18n'
];
<commit_msg>Fixed the breadcrumb on the edit users page<commit_after>/*************************************************
 * Copyright (c) 2015 Ansible, Inc.
 *
 * All Rights Reserved
 *************************************************/

/**
 * @ngdoc function
 * @name controllers.function:Users
 * @description This controller's the Users page
 */

import { N_ } from "../i18n";

const user_type_options = [
    { type: 'normal', label: N_('Normal User') },
    { type: 'system_auditor', label: N_('System Auditor') },
    { type: 'system_administrator', label: N_('System Administrator') },
];

function user_type_sync($scope) {
    return (type_option) => {
        $scope.is_superuser = false;
        $scope.is_system_auditor = false;
        switch (type_option.type) {
            case 'system_administrator':
                $scope.is_superuser = true;
                break;
            case 'system_auditor':
                $scope.is_system_auditor = true;
                break;
        }
    };
}

export function UsersList($scope, $rootScope, $stateParams,
    Rest, Alert, UserList, Prompt, ClearScope, ProcessErrors, GetBasePath,
    Wait, $state, $filter, rbacUiControlService, Dataset, i18n) {

    for (var i = 0; i < user_type_options.length; i++) {
        user_type_options[i].label = i18n._(user_type_options[i].label);
    }

    ClearScope();

    var list = UserList,
        defaultUrl = GetBasePath('users');

    init();

    function init() {
        $scope.canAdd = false;

        rbacUiControlService.canAdd('users')
            .then(function(canAdd) {
                $scope.canAdd = canAdd;
            });

        // search init
        $scope.list = list;
        $scope[`${list.iterator}_dataset`] = Dataset.data;
        $scope[list.name] = $scope[`${list.iterator}_dataset`].results;

        $rootScope.flashMessage = null;
        $scope.selected = [];
    }

    $scope.addUser = function() {
        $state.go('users.add');
    };

    $scope.editUser = function(id) {
        $state.go('users.edit', { user_id: id });
    };

    $scope.deleteUser = function(id, name) {

        var action = function() {
            $('#prompt-modal').modal('hide');
            Wait('start');
            var url = defaultUrl + id + '/';
            Rest.setUrl(url);
            Rest.destroy()
                .success(function() {
                    if (parseInt($state.params.user_id) === id) {
                        $state.go('^', null, { reload: true });
                    } else {
                        $state.go('.', null, { reload: true });
                    }
                })
                .error(function(data, status) {
                    ProcessErrors($scope, data, status, null, {
                        hdr: i18n._('Error!'),
                        msg: i18n.sprintf(i18n._('Call to %s failed. DELETE returned status: '), url) + status
                    });
                });
        };

        Prompt({
            hdr: i18n._('Delete'),
            body: '
' + i18n._('Are you sure you want to delete the user below?') + '

' + $filter('sanitize')(name) + '
',
            action: action,
            actionText: i18n._('DELETE')
        });
    };
}

UsersList.$inject = ['$scope', '$rootScope', '$stateParams',
    'Rest', 'Alert', 'UserList', 'Prompt', 'ClearScope', 'ProcessErrors', 'GetBasePath',
    'Wait', '$state', '$filter', 'rbacUiControlService', 'Dataset', 'i18n'
];

export function UsersAdd($scope, $rootScope, $stateParams, UserForm,
    GenerateForm, Rest, Alert, ProcessErrors, ReturnToCaller, ClearScope,
    GetBasePath, ResetForm, Wait, CreateSelect2, $state, $location, i18n) {

    ClearScope();

    var defaultUrl = GetBasePath('organizations'),
        form = UserForm;

    init();

    function init() {
        // apply form definition's default field values
        GenerateForm.applyDefaults(form, $scope);

        $scope.ldap_user = false;
        $scope.not_ldap_user = !$scope.ldap_user;
        $scope.ldap_dn = null;
        $scope.socialAuthUser = false;
        $scope.external_account = null;

        Rest.setUrl(GetBasePath('users'));
        Rest.options()
            .success(function(data) {
                if (!data.actions.POST) {
                    $state.go("^");
                    Alert(i18n._('Permission Error'), i18n._('You do not have permission to add a user.'), 'alert-info');
                }
            });

        $scope.user_type_options = user_type_options;
        $scope.user_type = user_type_options[0];
        $scope.$watch('user_type', user_type_sync($scope));
        CreateSelect2({
            element: '#user_user_type',
            multiple: false
        });
    }

    // Save
    $scope.formSave = function() {
        var fld, data = {};
        if ($scope[form.name + '_form'].$valid) {
            if ($scope.organization !== undefined && $scope.organization !== null && $scope.organization !== '') {
                Rest.setUrl(defaultUrl + $scope.organization + '/users/');
                for (fld in form.fields) {
                    if (form.fields[fld].realName) {
                        data[form.fields[fld].realName] = $scope[fld];
                    } else {
                        data[fld] = $scope[fld];
                    }
                }
                data.is_superuser = $scope.is_superuser;
                data.is_system_auditor = $scope.is_system_auditor;
                Wait('start');
                Rest.post(data)
                    .success(function(data) {
                        var base = $location.path().replace(/^\//, '').split('/')[0];
                        if (base === 'users') {
                            $rootScope.flashMessage = i18n._('New user successfully created!');
                            $rootScope.$broadcast("EditIndicatorChange", "users", data.id);
                            $state.go('users.edit', { user_id: data.id }, { reload: true });
                        } else {
                            ReturnToCaller(1);
                        }
                    })
                    .error(function(data, status) {
                        ProcessErrors($scope, data, status, form, { hdr: i18n._('Error!'), msg: i18n._('Failed to add new user. POST returned status: ') + status });
                    });
            } else {
                $scope.organization_name_api_error = i18n._('A value is required');
            }
        }
    };

    $scope.formCancel = function() {
        $state.go('users');
    };

    // Password change
    $scope.clearPWConfirm = function(fld) {
        // If password value changes, make sure password_confirm must be re-entered
        $scope[fld] = '';
        $scope[form.name + '_form'][fld].$setValidity('awpassmatch', false);
    };
}

UsersAdd.$inject = ['$scope', '$rootScope', '$stateParams', 'UserForm', 'GenerateForm',
    'Rest', 'Alert', 'ProcessErrors', 'ReturnToCaller', 'ClearScope', 'GetBasePath',
    'ResetForm', 'Wait', 'CreateSelect2', '$state', '$location', 'i18n'
];

export function UsersEdit($scope, $rootScope, $location,
    $stateParams, UserForm, Rest, ProcessErrors,
    ClearScope, GetBasePath, ResetForm, Wait, CreateSelect2, $state, i18n) {

    for (var i = 0; i < user_type_options.length; i++) {
        user_type_options[i].label = i18n._(user_type_options[i].label);
    }
    ClearScope();

    var form = UserForm,
        master = {},
        id = $stateParams.user_id,
        defaultUrl = GetBasePath('users') + id;

    init();

    function init() {
        $scope.user_type_options = user_type_options;
        $scope.user_type = user_type_options[0];
        $scope.$watch('user_type', user_type_sync($scope));
        Rest.setUrl(defaultUrl);
        Wait('start');
        Rest.get(defaultUrl).success(function(data) {
                $scope.user_id = id;
                $scope.ldap_user = (data.ldap_dn !== null && data.ldap_dn !== undefined && data.ldap_dn !== '') ? true : false;
                $scope.not_ldap_user = !$scope.ldap_user;
                master.ldap_user = $scope.ldap_user;
                $scope.socialAuthUser = (data.auth.length > 0) ? true : false;
                $scope.external_account = data.external_account;

                $scope.user_type = $scope.user_type_options[0];
                $scope.is_system_auditor = false;
                $scope.is_superuser = false;
                if (data.is_system_auditor) {
                    $scope.user_type = $scope.user_type_options[1];
                    $scope.is_system_auditor = true;
                }
                if (data.is_superuser) {
                    $scope.user_type = $scope.user_type_options[2];
                    $scope.is_superuser = true;
                }

                $scope.user_obj = data;
                $scope.name = data.username;

                CreateSelect2({
                    element: '#user_user_type',
                    multiple: false
                });

                $scope.$watch('user_obj.summary_fields.user_capabilities.edit', function(val) {
                    if (val === false) {
                        $scope.canAdd = false;
                    }
                });

                setScopeFields(data);
                Wait('stop');
            })
            .error(function(data, status) {
                ProcessErrors($scope, data, status, null, {
                    hdr: i18n._('Error!'),
                    msg: i18n.sprintf(i18n._('Failed to retrieve user: %s. GET status: '), $stateParams.id) + status
                });
            });
    }

    function setScopeFields(data) {
        _(data)
            .pick(function(value, key) {
                return form.fields.hasOwnProperty(key) === true;
            })
            .forEach(function(value, key) {
                $scope[key] = value;
            })
            .value();
        return;
    }

    $scope.convertApiUrl = function(str) {
        if (str) {
            return str.replace("api/v1", "#");
        } else {
            return null;
        }
    };

    // prepares a data payload for a PUT request to the API
    var processNewData = function(fields) {
        var data = {};
        _.forEach(fields, function(value, key) {
            if ($scope[key] !== '' && $scope[key] !== null && $scope[key] !== undefined) {
                data[key] = $scope[key];
            }
        });
        data.is_superuser = $scope.is_superuser;
        data.is_system_auditor = $scope.is_system_auditor;
        return data;
    };

    $scope.formCancel = function() {
        $state.go('users', null, { reload: true });
    };

    $scope.formSave = function() {
        $rootScope.flashMessage = null;
        if ($scope[form.name + '_form'].$valid) {
            Rest.setUrl(defaultUrl + '/');
            var data = processNewData(form.fields);
            Rest.put(data).success(function() {
                    $state.go($state.current, null, { reload: true });
                })
                .error(function(data, status) {
                    ProcessErrors($scope, data, status, null, {
                        hdr: i18n._('Error!'),
                        msg: i18n.sprintf(i18n._('Failed to retrieve user: %s. GET status: '), $stateParams.id) + status
                    });
                });
        }
    };

    $scope.clearPWConfirm = function(fld) {
        // If password value changes, make sure password_confirm must be re-entered
        $scope[fld] = '';
        $scope[form.name + '_form'][fld].$setValidity('awpassmatch', false);
        $rootScope.flashMessage = null;
    };
}

UsersEdit.$inject = ['$scope', '$rootScope', '$location',
    '$stateParams', 'UserForm', 'Rest', 'ProcessErrors', 'ClearScope', 'GetBasePath',
    'ResetForm', 'Wait', 'CreateSelect2', '$state', 'i18n'
];
<|endoftext|>


<commit_before>// /************************************
//  * Copyright (c) 2014 AnsibleWorks, Inc.
//  *
//  *
//  *  Portal.js
//  *
//  *  Controller functions for portal mode
//  *
//  */

// /**
//  * @ngdoc function
//  * @name controllers.function:Portal
//  * @description This controller's for portal mode
// */
// 'use strict';

// /**
//  * @ngdoc method
//  * @name controllers.function:Portal#Portal
//  * @methodOf controllers.function:Portal
//  * @description portal mode woohoo
//  *
//  *
// */
// function Portal($scope, $compile, $routeParams, $rootScope, $location, $log, Wait,
//     ClearScope, Stream, Rest, GetBasePath, ProcessErrors, Button){

//     ClearScope('portal');

//     // var buttons, html, e, waitCount, loadedCount,borderStyles, jobs_scope, schedule_scope;

//     // // Add buttons to the top of the Home page. We're using lib/ansible/generator_helpers.js-> Buttons()
//     // // to build buttons dynamically and insure all styling and icons match the rest of the application.
//     // buttons = {
//     //     refresh: {
//     //         mode: 'all',
//     //         awToolTip: "Refresh the page",
//     //         ngClick: "refresh()",
//     //         ngShow:"socketStatus == 'error'"
//     //     },
//     //     stream: {
//     //         ngClick: "showActivity()",
//     //         awToolTip: "View Activity Stream",
//     //         mode: 'all'
//     //     }
//     // };

//     // html = Button({
//     //     btn: buttons.refresh,
//     //     action: 'refresh',
//     //     toolbar: true
//     // });

//     // html += Button({
//     //     btn: buttons.stream,
//     //     action: 'stream',
//     //     toolbar: true
//     // });

//     // e = angular.element(document.getElementById('home-list-actions'));
//     // e.html(html);
//     // $compile(e)($scope);

//     // waitCount = 4;
//     // loadedCount = 0;

//     // if (!$routeParams.login) {
//     //     // If we're not logging in, start the Wait widget. Otherwise, it's already running.
//     //     //Wait('start');
//     // }

//     // if ($scope.removeWidgetLoaded) {
//     //     $scope.removeWidgetLoaded();
//     // }
//     // $scope.removeWidgetLoaded = $scope.$on('WidgetLoaded', function (e, label, jobscope, schedulescope) {
//     //     // Once all the widgets report back 'loaded', turn off Wait widget
//     //     if(label==="dashboard_jobs"){
//     //         jobs_scope = jobscope;
//     //         schedule_scope = schedulescope;
//     //     }
//     //     loadedCount++;
//     //     if (loadedCount === waitCount) {
//     //         $(window).resize(_.debounce(function() {
//     //             $scope.$emit('ResizeJobGraph');
//     //             $scope.$emit('ResizeHostGraph');
//     //             $scope.$emit('ResizeHostPieGraph');
//     //             Wait('stop');
//     //         }, 500));
//     //         $(window).resize();
//     //     }
//     // });

//     // if ($scope.removeDashboardReady) {
//     //     $scope.removeDashboardReady();
//     // }
//     // $scope.removeDashboardReady = $scope.$on('dashboardReady', function (e, data) {
//     //     nv.dev=false;

//     //     borderStyles = {"border": "1px solid #A9A9A9",
//     //         "border-radius": "4px",
//     //         "padding": "5px",
//     //         "margin-bottom": "15px"};
//     //     $('.graph-container').css(borderStyles);

//     //     var winHeight = $(window).height(),
//     //     available_height = winHeight - $('#main-menu-container .navbar').outerHeight() - $('#count-container').outerHeight() - 120;
//     //     $('.graph-container').height(available_height/2);
//     //     // // chart.update();

//     //     DashboardCounts({
//     //         scope: $scope,
//     //         target: 'dash-counts',
//     //         dashboard: data
//     //     });

//     //     JobStatusGraph({
//     //         scope: $scope,
//     //         target: 'dash-job-status-graph',
//     //         dashboard: data
//     //     });

//     //     if ($rootScope.user_is_superuser === true) {
//     //         waitCount = 5;
//     //         HostGraph({
//     //             scope: $scope,
//     //             target: 'dash-host-count-graph',
//     //             dashboard: data
//     //         });
//     //     }
//     //     else{
//     //         $('#dash-host-count-graph').remove(); //replaceWith("

");
//     //     }
//     //     DashboardJobs({
//     //         scope: $scope,
//     //         target: 'dash-jobs-list',
//     //         dashboard: data
//     //     });
//     //     HostPieChart({
//     //         scope: $scope,
//     //         target: 'dash-host-status-graph',
//     //         dashboard: data
//     //     });

//     // });

//     // if ($rootScope.removeJobStatusChange) {
//     //     $rootScope.removeJobStatusChange();
//     // }
//     // $rootScope.removeJobStatusChange = $rootScope.$on('JobStatusChange', function() {
//     //     jobs_scope.refreshJobs();
//     //     $scope.$emit('ReloadJobStatusGraph');

//     // });

//     // if ($rootScope.removeScheduleChange) {
//     //     $rootScope.removeScheduleChange();
//     // }
//     // $rootScope.removeScheduleChange = $rootScope.$on('ScheduleChange', function() {
//     //     schedule_scope.refreshSchedules();
//     //     $scope.$emit('ReloadJobStatusGraph');
//     // });

//     // $scope.showActivity = function () {
//     //     Stream({
//     //         scope: $scope
//     //     });
//     // };

//     // $scope.refresh = function () {
//     //     Wait('start');
//     //     loadedCount = 0;
//     //     Rest.setUrl(GetBasePath('dashboard'));
//     //     Rest.get()
//     //         .success(function (data) {
//     //             $scope.$emit('dashboardReady', data);
//     //         })
//     //         .error(function (data, status) {
//     //             ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to get dashboard: ' + status });
//     //         });
//     // };

//     // $scope.refresh();

// }

// Home.$inject = ['$scope', '$compile', '$routeParams', '$rootScope', '$location', '$log','Wait',
//     'ClearScope', 'Stream', 'Rest', 'GetBasePath', 'ProcessErrors', 'Button'
// ];
<commit_msg>adding controller for portal mode.<commit_after>/************************************
 * Copyright (c) 2014 AnsibleWorks, Inc.
 *
 *
 *  Portal.js
 *
 *  Controller functions for portal mode
 *
 */

/**
 * @ngdoc function
 * @name controllers.function:Portal
 * @description This controller's for portal mode
*/
'use strict';

/**
 * @ngdoc method
 * @name controllers.function:Portal#Portal
 * @methodOf controllers.function:Portal
 * @description portal mode woohoo
 *
 *
*/
function PortalController($scope, $compile, $routeParams, $rootScope, $location, $log, Wait, ClearScope, Stream, Rest, GetBasePath, ProcessErrors,
    Button, PortalJobTemplate, GenerateList, JobTemplateList, SearchInit, PaginateInit, PlaybookRun){

        ClearScope('portal');

        var html,
        e,
        winHeight,
        available_height,
        list = JobTemplateList,
        view= GenerateList,
        defaultUrl = GetBasePath('job_templates'),
        buttons = {
            refresh: {
                mode: 'all',
                awToolTip: "Refresh the page",
                ngClick: "refresh()",
                ngShow:"socketStatus == 'error'"
            }
            // ,
            // stream: {
            //     ngClick: "showActivity()",
            //     awToolTip: "View Activity Stream",
            //     mode: 'all'
            // }
        };

        html = Button({
            btn: buttons.refresh,
            action: 'refresh',
            toolbar: true
        });

        // html += Button({
        //     btn: buttons.stream,
        //     action: 'stream',
        //     toolbar: true
        // });

        e = angular.element(document.getElementById('portal-list-actions'));
        e.html(html);
        $compile(e)($scope);

        if ($scope.removeLoadPortal) {
            $scope.removeLoadPortal();
        }
        $scope.removeLoadPortal = $scope.$on('LoadPortal', function () {
            winHeight = $(window).height();
            available_height = Math.floor(winHeight - $('#main-menu-container .navbar').outerHeight() - $('#refresh-row').outerHeight() - 45);
            $('.portal-container').height(available_height);

            view.inject( list, {
                id : 'portal-job-template',
                mode: 'edit',
                scope: $scope,
                breadCrumbs: false,
                searchSize: 'col-lg-6 col-md-6'
            });

            $rootScope.flashMessage = null;

            SearchInit({
                scope: $scope,
                set: 'job_templates',
                list: list,
                url: defaultUrl
            });
            PaginateInit({
                scope: $scope,
                list: list,
                url: defaultUrl
            });

            // Called from Inventories tab, host failed events link:
            if ($routeParams.name) {
                $scope[list.iterator + 'SearchField'] = 'name';
                $scope[list.iterator + 'SearchValue'] = $routeParams.name;
                $scope[list.iterator + 'SearchFieldLabel'] = list.fields.name.label;
            }

            $scope.search(list.iterator);

            PortalJobTemplate({
                scope: $scope,
                target: 'portal-jobs',
                // dashboard: data
            });

        });
        $scope.submitJob = function (id) {
            PlaybookRun({ scope: $scope, id: id });
        };

        $scope.refresh = function () {
            $scope.$emit('LoadPortal');
            // Wait('start');
            // loadedCount = 0;
            // Rest.setUrl(GetBasePath('dashboard'));
            // Rest.get()
            //     .success(function (data) {
            //         $scope.$emit('dashboardReady', data);
            //     })
            //     .error(function (data, status) {
            //         ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to get dashboard: ' + status });
            //     });
        };

        $scope.refresh();

    }

PortalController.$inject = ['$scope', '$compile', '$routeParams', '$rootScope', '$location', '$log','Wait', 'ClearScope', 'Stream', 'Rest', 'GetBasePath', 'ProcessErrors',
    'Button', 'PortalJobTemplate', 'GenerateList' , 'JobTemplateList', 'SearchInit', 'PaginateInit', 'PlaybookRun'
];
<|endoftext|>