Viewing File: /usr/local/cpanel/base/frontend/jupiter/site-monitor/views/listSiteMonitors.js

/*
# site-monitor/views/listSiteMonitors.js           Copyright 2021 cPanel, L.L.C.
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
*/

/* global define */

/** @namespace cpanel.siteMonitor.views.listSiteMonitors */

define(
    [
        "angular",
        "cjt/util/locale",
        "app/models/monitor-state.enum",
        "app/models/monitor-type.enum",
        "app/models/monitor",
        "app/services/sites",
        "app/services/monitoring",
        "app/services/contacts",
        "app/services/sitesCache",
        "app/services/batch",
        "cjt/services/alertService",
        "app/directives/itemListerDirective",
        "app/directives/siteItemListDirective",
        "cjt/services/cpanel/componentSettingSaverService",
        "cjt/services/viewNavigationApi",
        "app/services/dataStore",
    ],
    function(angular, LOCALE, MonitorState, MonitorType, Monitor) {

        "use strict";

        var app = angular.module("cpanel.siteMonitor.listSiteMonitors", [
            "cpanel.siteMonitor.siteItemListDirective",
            "cpanel.siteMonitor.itemListerDirective",
            "cpanel.siteMonitor.monitoringService",
            "cpanel.siteMonitor.batchService",
            "cpanel.siteMonitor.contactsService",
            "cjt2.services.viewNavigationApi",
            "cjt2.services.alert",
            "cpanel.siteMonitor.dataStoreService",
            "cpanel.siteMonitor.sitesCacheService",
        ]);

        /**
         * View Controller for Domain Listing
         *
         * @module listSites
         *
         * @param  {Object} $scope angular scope
         * @param  {Object} $locale angular location Object
         * @param  {Array}  sitesAPI api to fetch sites.
         * @param  {Object} ITEM_LISTER_CONSTANTS event constants for actions
         *
         */

        var COMPONENT_NAME = "siteMonitor.listView";

        var controller = app.controller(
            "listSiteMonitors",
            [
                "$scope",
                "$location",
                "$filter",
                "$timeout",
                "componentSettingSaverService",
                "initialSites",
                "viewNavigationApi",
                "dataStore",
                "sitesCache",
                "sites",
                "batch",
                "monitoring",
                "alertService",
                "contacts",
                "ITEM_LISTER_CONSTANTS",
                "PAGE",
                function(
                    $scope,
                    $location,
                    $filter,
                    $timeout,
                    $CSSS,
                    initialSites,
                    viewNavigationApi,
                    dataStore,
                    sitesCache,
                    sitesService,
                    batch,
                    monitoringAPI,
                    alertService,
                    contacts,
                    ITEM_LISTER_CONSTANTS,
                    PAGE) {

                    var LIST_DOMAIN_EVENTS = {
                        HIDE_ASSOCIATED: "hideAssociatedSubdomains",
                        SHOW_ASSOCIATED: "showAssociatedSubdomains"
                    };

                    var associatedDomainsExist;

                    $scope.LOCALE = LOCALE;
                    $scope.disableBtn = false;

                    /**
                     * Handles item buttons clicks.
                     *
                     * @method _itemChangeRequested
                     * @param {Event} event
                     * @param {*} parameters
                     */
                    function _itemChangeRequested(event, parameters) {
                        switch(parameters.actionType) {
                            case 'enable_multiple':
                                $scope.disableBtn = true;

                                var sites = parameters.items;

                                var queue = sites.map(function(site) {
                                    return { url: site.domain, fullUrl: "https://" + site.domain + "/", domain: site.domain };
                                });

                                dataStore.save("post-subscribe", queue);

                                // TODO: Move this to the store callback this once the subscribe flow is in place
                                _batchEnable(queue)
                                    .then(function(results) {
                                        _fetchAndRefresh()
                                    });

                                break;

                            case 'disable_multiple':
                                $scope.disableBtn = true;

                                var sites = parameters.items;

                                // filter out calls to remove monitors that don't exist
                                var queue = sites.filter(function(site) {
                                    if (site.monitors.length) { return true }
                                }).map(function(site) {
                                    var monitor = site.monitors[0];
                                    return { url: monitor.url(), id: monitor.id, domain: site.domain };
                                });

                                dataStore.save("post-unsubscribe", queue);

                                // TODO: Move this to the store callback this once the unsubscribe flow is in place
                                _batchDisable(queue)
                                    .then(function() {
                                        _fetchAndRefresh()
                                    });

                                break;

                            case 'enable':
                                $scope.disableBtn = true;

                                var site = parameters.item;

                                var queue = [ site ].map(function(site) {
                                    return { url : site.domain, fullUrl: "https://" + site.domain + "/" , domain: site.domain};
                                });

                                dataStore.save("post-subscribe", queue);

                                // TODO: Move this to the store callback this once the subscribe flow is in place
                                _batchEnable(queue)
                                    .then(function() {
                                        _fetchAndRefresh()
                                    });

                                break;

                            case 'disable':
                                $scope.disableBtn = true;
                                var site = parameters.item;
                                var monitor = site.monitors[0];

                                var queue = [
                                    { url: monitor.url(), id: monitor.id, domain: site.domain },
                                ];

                                dataStore.save("post-unsubscribe", queue);

                                // TODO: Move this to the store callback this once the unsubscribe flow is in place
                                _batchDisable(queue)
                                    .then(function() {
                                        _fetchAndRefresh();
                                    });

                                break;
                            case 'manage':
                                // TODO
                                break;
                        }
                    }

                    /**
                     * Fetches updated sites and broadcasts event to refresh UI
                     *
                     * @method _fetchAndRefresh
                     */
                    function _fetchAndRefresh() {
                        sitesService.get({refresh: true}).then(function(sites) {
                            $scope.disableBtn = false;
                            _updateFiltered();
                            //_updateAssociated(sites);
                            $scope.$broadcast(ITEM_LISTER_CONSTANTS.MONITOR_CHANGE_EVENT, sites );
                        });
                    }

                    /**
                     * Disable the monitors a few at a time so we don't flood the server or
                     * consume too much browser memory.
                     * @param { { url: string, id: string }[] } orders
                     * @returns
                     */
                    function _batchDisable(orders) {
                        var status = {
                            error: [],
                            success: [],
                        };

                        return batch
                            .uniform(
                                orders, 2,
                                function removeMonitor(order) {
                                    var monitor = sitesCache.findMonitor(order.domain, order.url);
                                    if (monitor) {
                                        monitor.state = MonitorState.Removing;
                                        $scope.$applyAsync();
                                    }
                                    return monitoringAPI.disable(order.id, order.url);
                                },
                                function identity(order) {
                                    return order.url;
                                },
                                function removeMonitorDone(order, error) {
                                    var monitor = sitesCache.findMonitor(order.domain, order.url);
                                    if (error)  {
                                        if (monitor) {
                                            monitor.state = MonitorState.Error;
                                        }
                                        alertService.add({
                                            type: "danger",
                                            message: LOCALE.maketext("Failed to remove the monitor [_1] with the error: [_2]", monitor.url(), error),
                                            closeable: true,
                                            replace: false,
                                        });
                                        status.error.push(monitor);
                                    } else {
                                        if (monitor) {
                                            monitor.state = MonitorState.Ready;
                                            $scope.$applyAsync();
                                        }
                                        status.success.push(monitor);
                                    }
                                }
                            )
                            .then(function(responses) {
                                if (status.success.length > 0 && status.error.length > 0) {
                                    alertService.success({
                                        message: LOCALE.maketext("The system successfully removed some of the requested monitors."),
                                        replace: false
                                    });
                                } else if (status.success.length > 0 && status.error.length === 0) {
                                    alertService.success({
                                        message: LOCALE.maketext("The system successfully removed the requested monitors."),
                                        replace: false
                                    });
                                }
                            });
                    }

                    /**
                     * Enable the monitors a few at a time so we don't flood the server or
                     * consume too much browser memory.
                     * @param { { url: string}[] } orders
                     * @returns
                     */
                    function _batchEnable(orders) {

                        // Create placholder monitor rows
                        orders.forEach(function(order) {
                            var site = sitesCache.findByDomainName(order.domain);
                            if (site) {
                                var newMonitor = Monitor.parseItem({
                                    url: order.fullUrl,
                                    name: order.url,
                                    type: MonitorType.https,
                                    state: MonitorState.None,
                                });
                                site.addMonitor(newMonitor);
                            }
                        });

                        return contacts
                            .getStoreEmailAddress()
                            .then(
                                function(storeEmail) {

                                    // CONSIDER: We should consider using the contacts email if the store one is not available.

                                    if (!storeEmail) {
                                        var message = LOCALE.maketext("The system could not find the an email address to use when setting up your monitors.");
                                        alertService.add({
                                            type: "danger",
                                            message: message,
                                            closeable: true,
                                            replace: false,
                                        });
                                        throw new Error(message);
                                    }

                                    var status = {
                                        error: [],
                                        success: [],
                                    };

                                    return batch
                                        .uniform(
                                            orders, 2,
                                            function createMonitor(order) {
                                                var monitor = sitesCache.findMonitor(order.domain, order.fullUrl);
                                                monitor.state = MonitorState.Creating;
                                                $scope.$applyAsync();
                                                return monitoringAPI.enable(order.url, null, [ storeEmail ]);
                                            },
                                            function identity(order) {
                                                return order.url;
                                            },
                                            function createMonitorDone(order, error) {
                                                var monitor = sitesCache.findMonitor(order.domain, order.fullUrl);
                                                if (error)  {
                                                    monitor.state = MonitorState.Error;
                                                    alertService.add({
                                                        type: "danger",
                                                        message: LOCALE.maketext("Failed to create the monitor [_1] with the error: [_2]", monitor.url, error),
                                                        closeable: true,
                                                        replace: false,
                                                    });
                                                    status.error.push(monitor);
                                                } else {
                                                    monitor.state = MonitorState.Ready;
                                                    status.success.push(monitor);
                                                }
                                                $scope.$applyAsync();
                                            }
                                        )
                                        .then(function(responses) {
                                            if (status.success.length > 0 && status.error.length > 0) {
                                                alertService.success({
                                                    message: LOCALE.maketext("The system successfully created some of the requested monitors."),
                                                    replace: false
                                                });
                                            } else if (status.success.length > 0 && status.error.length === 0) {
                                                alertService.success({
                                                    message: LOCALE.maketext("The system successfully created the requested monitors."),
                                                    replace: false
                                                });
                                            }
                                        });
                                }
                            );
                    }

                    /**
                     * Update the flag use to check if there are associated domains.
                     *
                     * QUESTION: Do we need this???
                     *
                     * @method _updateAssociated
                     * @param {Sites} sites
                     */
                    function _updateAssociated(sites) {
                        associatedDomainsExist = sites.some(function(site) {
                            if (site.associatedAddonDomain) {
                                return true;
                            }
                            return false;
                        });
                    }

                    /**
                     * Handles other item events like changing selection.
                     *
                     * @method _itemListerUpdated
                     * @param {Event} event
                     * @param {*} parameters
                     */
                    function _itemListerUpdated(event, parameters) {
                        // DOESN'T DO ANYTHING BESIDES CAUSE A CONSOLE ERROR ATM, UNCOMMENTED LINE THAT CALLS THIS
                        $scope.currentSearchFilterValue = parameters.meta.filterValue;
                    }

                    /**
                     * On updating of the show associated addon domains checkbox, refilter sites
                     *
                     * @private
                     * @method _filterAssociatedDomains
                     * @param {*} event
                     */
                    function _filterAssociatedDomains(domain) {
                        if ($scope.showAssociatedSubdomains) {
                            return true;
                        }
                        if (!domain.associatedAddonDomain) {
                            return true;
                        }

                        return false;
                    }

                    var lastFiltered = true;

                    /**
                     * Reapply the filters based on new input from the user.
                     *
                     * @private
                     * @method _updateFiltered
                     */
                    function _updateFiltered() {
                        var filteredSites = $filter("filter")(sitesCache.get(), _filterAssociatedDomains);
                        lastFiltered = $scope.showAssociatedSubdomains;
                        $scope.filteredSites = filteredSites;
                    }

                    /**
                     * Show and hide the associated subdomains for a domain.
                     *
                     * @scope
                     * @method toggleShowAssociatedSubdomains
                     */
                    $scope.toggleShowAssociatedSubdomains = function toggleShowAssociatedSubdomains() {
                        $scope.showAssociatedSubdomains = !$scope.showAssociatedSubdomains;
                        $CSSS.set(COMPONENT_NAME, { showAssociatedSubdomains: $scope.showAssociatedSubdomains });
                        _updateFiltered();
                        _updateConfiguration();
                    }

                    /**
                     * Gets the list of sites to show in the view.
                     *
                     * @scope
                     * @method getSites
                     * @returns
                     */
                    $scope.getSites = function getSites() {
                        if (lastFiltered !== $scope.showAssociatedSubdomains) {
                            _updateFiltered();
                        }
                        return $scope.filteredSites;
                    }

                    /**
                     * Updates the configuration array passed to the child component
                     *
                     * @method _updateConfiguration
                     * @private
                     * @returns
                     */
                    function _updateConfiguration() {

                        // remove all items from config
                        $scope.configuration.splice(0);

                        if (!associatedDomainsExist) {
                            return;
                        }

                        if ($scope.showAssociatedSubdomains) {
                            $scope.configuration.push({
                                label: LOCALE.maketext("Hide Associated Subdomains"),
                                event: LIST_DOMAIN_EVENTS.HIDE_ASSOCIATED
                            });
                        } else {
                            $scope.configuration.push({
                                label: LOCALE.maketext("Show Associated Subdomains"),
                                event: LIST_DOMAIN_EVENTS.SHOW_ASSOCIATED
                            });
                        }
                    }

                    $scope.configuration = [];
                    _updateConfiguration();

                    $scope.$on(ITEM_LISTER_CONSTANTS.ITEM_CLICKED_EVENT, _itemChangeRequested);
                    //$scope.$on(ITEM_LISTER_CONSTANTS.ITEM_SELECT_EVENT, _itemListerUpdated);
                    $scope.$on(LIST_DOMAIN_EVENTS.SHOW_ASSOCIATED, $scope.toggleShowAssociatedSubdomains);
                    $scope.$on(LIST_DOMAIN_EVENTS.HIDE_ASSOCIATED, $scope.toggleShowAssociatedSubdomains);

                    $scope.showAssociatedSubdomains = false;
                    $scope.headers = [
                        {
                            field: "batchSelect",
                            class: "batch-select-column",
                            sortable: false,
                            label: null
                        },
                        {
                            field: "domain",
                            sortable: true,
                            class: "domain-column",
                            label: LOCALE.maketext("Site")
                        },
                        {
                            field: "documentRoot",
                            class: "docroot-column",
                            sortable: true,
                            label: LOCALE.maketext("Document Root"),
                            hiddenInSmall: true
                        },
                        {
                            field: "monitors",
                            class: "monitors-column",
                            sortable: true,
                            label: LOCALE.maketext("Monitors"),
                            hiddenInSmall: true
                        },
                        {
                            field: "actions",
                            class: "actions-column",
                            label: LOCALE.maketext("Actions"),
                            hiddenInSmall: true
                        }
                    ];

                    $CSSS.register(COMPONENT_NAME)
                        .then(function _savedStateLoaded(config) {
                            if (config && $scope.showAssociatedSubdomains !== config.showAssociatedSubdomains) {
                                $scope.showAssociatedSubdomains = config.showAssociatedSubdomains;
                                _updateFiltered();
                                _updateConfiguration();
                            }
                        });

                    $scope.$on("$destroy", function() {
                        $CSSS.unregister(COMPONENT_NAME);
                    });

                    if (initialSites instanceof Error) {
                        alertService.add({
                            type: "danger",
                            message: initialSites.message,
                            closeable: true,
                            replace: true,
                        });
                        $scope.filteredSites = [];
                    } else {
                        $scope.filteredSites = initialSites;
                    }
                }
            ]
        );

        return controller;
    }
);

Back to Directory File Manager