Viewing File: /usr/local/cpanel/base/frontend/jupiter/file_and_directory_restoration/views/list.js

/*
# file_and_directory_restoration/views/list.js
#                                                    Copyright 2022 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: false */

define(
    [
        "angular",
        "lodash",
        "cjt/util/table",
        "cjt/util/locale",
        "cjt/util/parse",
        "cjt/decorators/paginationDecorator",
        "cjt/directives/actionButtonDirective",
        "cjt/validator/datatype-validators",
        "app/filters/fileSizeFilter",
        "app/services/backupAPI",
        "cjt/services/alertService",
        "cjt/directives/alert",
        "cjt/directives/alertList",
        "cjt/services/cpanel/componentSettingSaverService",
    ],
    function(angular, _, Table, LOCALE, PARSE) {
        "use strict";

        // Retrieve the current application
        var app = angular.module("App");
        app.value("PAGE", PAGE);

        // Setup the controller
        var controller = app.controller(
            "listController", [
                "$scope",
                "$anchorScroll",
                "PAGE",
                "backupAPIService",
                "alertService",
                "componentSettingSaverService",
                function(
                    $scope,
                    $anchorScroll,
                    PAGE,
                    backupAPIService,
                    alertService,
                    componentSettingSaverService
                ) {

                    var directoryContentsTable = new Table();
                    directoryContentsTable.setSort("name", "asc");

                    var backupsTable = new Table();
                    backupsTable.setSort("backupDate,backupType,lastModifiedTime,fileSize", "desc");

                    $scope.setDirectoryContentsPage = function(updatePageSize) {
                        $scope.clearBackupList();
                        $scope.actions.loadingData = true;
                        if (updatePageSize) {
                            setPagination("pagination");
                        } else {
                            getDirectoryContents($scope.currentDirectory, $scope.directoryContentsMeta.pageNumber, $scope.directoryContentsMeta.pageSize);
                        }
                    };

                    $scope.navigateBreadcrumb = function(directoryPath) {
                        $scope.clearBackupList();
                        $scope.actions.loadingData = true;
                        var parsedPath = "/";
                        for (var i = 0, len = $scope.breadCrumb.length; i < len; i++) {
                            if (directoryPath === $scope.breadCrumb[i]) {
                                parsedPath = parsedPath + $scope.breadCrumb[i] + "/";
                                break;
                            } else {
                                parsedPath = parsedPath + $scope.breadCrumb[i] + "/";
                            }

                        }
                        $scope.currentDirectory = parsedPath;
                        var pageNumber = 1;
                        getDirectoryContents($scope.currentDirectory, pageNumber, $scope.directoryContentsMeta.pageSize);
                        buildBreadcrumb($scope.currentDirectory);
                    };

                    $scope.goToDirectory = function(directoryPath) {
                        $scope.actions.loadingData = true;
                        if (directoryPath === "/") {
                            $scope.breadcrumb = "";
                        }

                        // Remove backup list if navigating to a different directory
                        $scope.clearBackupList();

                        // Reset current page to beginning of list when navigating to new directory
                        if ($scope.currentDirectory !== directoryPath) {
                            $scope.directoryContentsMeta.pageNumber = 1;
                        }


                        $scope.currentDirectory = directoryPath;
                        var pathLength = $scope.currentDirectory.length;

                        if ($scope.currentDirectory.charAt(pathLength - 1) !== "/") {
                            $scope.currentDirectory = $scope.currentDirectory + "/";
                        }
                        getDirectoryContents($scope.currentDirectory, $scope.directoryContentsMeta.pageNumber, $scope.directoryContentsMeta.pageSize);
                        buildBreadcrumb($scope.currentDirectory);
                    };

                    $scope.toggleSelectedBackup = function(backupDate) {
                        if (backupDate === $scope.backupSelected) {
                            $scope.backupSelected = "";
                        } else {
                            $scope.backupSelected = backupDate;
                        }
                    };

                    $scope.listBackups = function(content) {

                        // when retrieving backup by directory browse, query_file_info API call
                        // does not need to check for item existing
                        var checkForExists = 0;
                        $scope.actions.loadingBackups = true;
                        return getBackupList(content.backupPath, checkForExists, content.exists);
                    };

                    $scope.toggleRestoreConfirmation = function(backup) {
                        if (backup) {
                            $scope.confirmSelected = backup.backupDate;
                            $scope.isConfirmingRestoration = true;
                        } else {
                            $scope.confirmSelected = "";
                            $scope.isConfirmingRestoration = false;
                        }

                    };

                    $scope.restoreSelectedBackup = function(backup) {
                        return restoreBackup(backup);
                    };

                    $scope.goToParentDirectory = function() {
                        $scope.actions.loadingData = true;
                        $scope.currentDirectory = buildParentDirectoryPath();
                        var pageNumber = 1;
                        getDirectoryContents($scope.currentDirectory, pageNumber, $scope.directoryContentsMeta.pageSize);
                        buildBreadcrumb($scope.currentDirectory);
                    };

                    $scope.findByPathInput = function(path) {

                        // when getting backups by path input we need the query_file_info API to return if that item
                        // exists locally
                        var exists = 1;
                        path = checkForSlashAtStart(path);
                        $scope.getBackupsError = "";
                        $scope.selectedContent = path;
                        return getBackupList(path, exists);
                    };

                    /**
                     * Jump to specified page
                     *
                     * @param {Number} pageNumber - page number that user is going to
                     * @param {String} currentPath - current directory path
                     */
                    $scope.goToPage = function(pageNumber, currentDirectory) {
                        var pageExists = checkIfPageExists(pageNumber);

                        // when the page input is empty do not do anything
                        if (pageNumber === null || isNaN(pageNumber)) {
                            return;
                        } else {
                            if (pageExists) {
                                getDirectoryContents(currentDirectory, pageNumber, $scope.directoryContentsMeta.pageSize);
                            } else {
                                $scope.pageDoesNotExist = true;
                            }
                        }
                    };

                    $scope.sortDirectoryContentsTable = function() {

                        // necessary because Table directive pagination is not handling total items
                        var totalItems = $scope.directoryContentsMeta.totalItems;

                        if ($scope.directoryContentsMeta.pageNumber >= 2) {
                            var tempPageNumber = $scope.directoryContentsMeta.pageNumber;
                            directoryContentsTable.meta.pageNumber = 1;
                            directoryContentsTable.update();
                            directoryContentsTable.meta.pageNumber = tempPageNumber;
                        } else {
                            directoryContentsTable.update();
                        }


                        $scope.directoryContentsMeta.totalItems = totalItems;
                        $scope.directoryContents = directoryContentsTable.getList();
                    };

                    $scope.sortBackupsTable = function() {
                        backupsTable.update();
                        $scope.backupList = backupsTable.getList();
                        $scope.backupsPaginationMessage = backupsTable.paginationMessage();
                    };

                    $scope.clearBackupList = function() {
                        $scope.isConfirmingRestoration = false;
                        $scope.getBackupsError = "";
                        $scope.isBackupSelected = false;
                        $scope.selectedContent = "";
                    };

                    $scope.checkForEmptyInput = function(pathInput) {
                        if (pathInput === "") {
                            $scope.isPathInputEmpty = true;
                        } else {
                            $scope.isPathInputEmpty = false;
                        }
                    };

                    $scope.getBackupsPanelClass = function(isPanelOpen) {
                        var panelClass = "panel panel-default";
                        if (isPanelOpen) {
                            panelClass = panelClass + " restorationPanel";
                        }
                        return panelClass;
                    };

                    $scope.getDirContentsPanelClass = function(isPanelOpen) {
                        var panelClass = "panel panel-default";
                        if (isPanelOpen) {
                            panelClass = panelClass + " restorationPanel";
                        }
                        return panelClass;
                    };

                    $scope.scrollToBackupList = function() {
                        $anchorScroll("viewContent");
                    };

                    function checkForSlashAtStart(path) {
                        if (path.indexOf("/") !== 0) {
                            path = "/" + path;
                        }
                        return path;
                    }

                    function getDirectoryContents(directoryPath, pageNumber, pageSize) {
                        clearDirectoryContentsTableData();

                        backupAPIService.listDirectoryContents(directoryPath, pageNumber, pageSize)
                            .then(function(directoryContents) {
                                var tempContents = buildBackupPaths(directoryContents.data);
                                loadDirectoryContentsTable(tempContents, directoryContents.meta.paginate);
                            })
                            .catch(function(error) {
                                $scope.noMetadataMessage = error;
                            })
                            .finally(function() {
                                $scope.actions.loadingUI = false;
                                $scope.actions.loadingData = false;
                                if ($scope.directoryContents.length === 0) {
                                    $scope.emptyDirectory = true;
                                } else {
                                    $scope.emptyDirectory = false;
                                }
                            });
                    }

                    function loadDirectoryContentsTable(directoryContents, pagination) {
                        directoryContentsTable.load(directoryContents);
                        createGoToPageNumbers(pagination);
                        updateDirectoryContentsTable(pagination);
                    }

                    function updateDirectoryContentsTable(pagination) {

                        // This is a hacky way of making sure that the table is updated properly
                        $scope.directoryContentsMeta.pageNumber = 1;

                        directoryContentsTable.update();

                        // Overwrite pagination created by table because API call was paginated
                        $scope.directoryContentsMeta.maxPages = parseInt(pagination.total_pages, 10);
                        $scope.directoryContentsMeta.totalItems = parseInt(pagination.total_records, 10);
                        $scope.directoryContentsMeta.start = parseInt(pagination.current_record, 10);
                        $scope.directoryContentsMeta.pageNumber = pagination.current_page;

                        if (($scope.directoryContentsMeta.start + $scope.directoryContentsMeta.pageSize) > $scope.directoryContentsMeta.totalItems) {
                            $scope.directoryContentsMeta.limit = $scope.directoryContentsMeta.totalItems;
                        } else {
                            $scope.directoryContentsMeta.limit = ($scope.directoryContentsMeta.start + $scope.directoryContentsMeta.pageSize) - 1;
                        }

                        $scope.directoryContents = directoryContentsTable.getList();
                        $scope.directoryContentsPaginationMessage = directoryContentsTable.paginationMessage();
                    }

                    function clearDirectoryContentsTableData() {
                        directoryContentsTable.items = [];
                        directoryContentsTable.filteredList = [];
                        directoryContentsTable.last_id = 0;
                    }

                    function buildBackupPaths(directoryContents) {
                        var addedPath = [];

                        directoryContents.forEach(function(content) {
                            if (!content.backupPath || !content.parentDir) {
                                if ($scope.currentDirectory === "/") {
                                    content["backupPath"] = "/" + content.name;
                                    content["parentDir"] = "/";
                                } else {
                                    content["backupPath"] = $scope.currentDirectory + content.name;
                                    content["parentDir"] = $scope.currentDirectory;
                                }
                            }
                            addedPath.push(content);
                        });
                        $scope.parentDirectory = $scope.currentDirectory;
                        return addedPath;
                    }

                    function buildBreadcrumb(content) {
                        var breadCrumbArray = content.split("/");
                        $scope.breadCrumb = breadCrumbArray.slice(1, breadCrumbArray.length - 1);
                    }

                    function buildParentDirectoryPath() {
                        var parentDirectoryPath = "/";
                        for (var i = 0, len = $scope.breadCrumb.length - 1; i < len; i++) {
                            parentDirectoryPath = parentDirectoryPath + $scope.breadCrumb[i] + "/";

                        }
                        return parentDirectoryPath;
                    }

                    function createBackupTable() {
                        backupsTable.update();
                        $scope.backupsMeta = backupsTable.getMetadata();
                        $scope.backupList = backupsTable.getList();
                        $scope.backupsPaginationMessage = backupsTable.paginationMessage();
                    }

                    function getBackupList(backupPath, shouldReturnExists, doesContentExist) {
                        $scope.clearBackupList();
                        return backupAPIService.listBackups(backupPath, shouldReturnExists)
                            .then(function(backupList) {
                                if (shouldReturnExists) {
                                    $scope.doesContentExist = PARSE.parsePerlBoolean(backupList[0].exists);
                                }
                                $anchorScroll("viewContent");
                                $scope.isContentTypeDirectory = backupList[0].type === "Directory" ? true : false;
                                $scope.isBackupSelected = true;
                                backupsTable.load(backupList);
                                createBackupTable();
                            })
                            .catch(function(error) {
                                $scope.getBackupsError = error;
                            })
                            .finally(function() {
                                if (!shouldReturnExists) {
                                    $scope.doesContentExist = doesContentExist;
                                }
                                $scope.selectedContent = backupPath;
                                $scope.actions.loadingBackups = false;
                            });
                    }

                    function getDirectoryContentsPagination(componentName) {
                        componentSettingSaverService.get(componentName)
                            .then(function(pagination) {
                                if (!pagination) {
                                    registerComponent(componentName);
                                } else {
                                    $scope.directoryContentsMeta.pageSize = pagination.pageSize;
                                    getDirectoryContents($scope.currentDirectory, $scope.directoryContentsMeta.pageNumber, $scope.directoryContentsMeta.pageSize);
                                }
                            })
                            .catch(function(error) {
                                alertService.add({
                                    type: "danger",
                                    message: error,
                                    group: "backup-restoration",
                                    closeable: true
                                });
                            });
                    }

                    function setPagination(componentName) {
                        componentSettingSaverService.set(componentName, {
                            pageSize: $scope.directoryContentsMeta.pageSize
                        })
                            .then(function(response) {
                                getDirectoryContents($scope.currentDirectory, $scope.directoryContentsMeta.pageNumber, $scope.directoryContentsMeta.pageSize);
                            })
                            .catch(function(error) {
                                alertService.add({
                                    type: "danger",
                                    message: error,
                                    group: "backup-restortion",
                                    closeable: true
                                });
                            });
                    }

                    function registerComponent(componentName) {
                        componentSettingSaverService.register(componentName)
                            .then(function(componentResponse) {
                                setPagination(componentName, true);
                            })
                            .catch(function(error) {
                                alertService.add({
                                    type: "danger",
                                    message: error,
                                    group: "backup-restoration",
                                    closeable: true
                                });
                            });

                    }

                    function restoreBackup(backup) {
                        $scope.actions.restoring = true;
                        return backupAPIService.restoreBackup(backup.path, backup.backupID)
                            .then(function(response) {
                                alertService.add({
                                    type: "success",
                                    message: LOCALE.maketext("The system successfully restored the “[_1]” backup file from the date “[_2]”.", _.escape(backup.path), _.escape(backup.backupDate)),
                                    autoClose: 10000,
                                    group: "backup-restoration"
                                });
                                $scope.clearBackupList();
                                $scope.goToDirectory($scope.currentDirectory);
                            })
                            .catch(function(error) {
                                alertService.add({
                                    type: "danger",
                                    message: error,
                                    closeable: true,
                                    group: "backup-restoration"
                                });
                            })
                            .finally(function() {
                                $scope.actions.restoring = false;
                                $scope.toggleRestoreConfirmation();
                            });
                    }

                    function checkIfPageExists(pageNumber) {
                        if (pageNumber * $scope.directoryContentsMeta.page_size > $scope.directoryContentsMeta.total_records) {
                            return false;
                        } else {
                            return true;
                        }
                    }

                    function createGoToPageNumbers(metadata) {
                        var goToPages = [];
                        var i = 1;
                        while (i <= metadata.total_pages) {
                            i.toString();
                            goToPages.push(i);
                            parseInt(i, 10);
                            i++;
                        }
                        $scope.goToPages = goToPages;
                    }

                    function init() {
                        var paginationComponent = "pagination";

                        // root dir representing /home/USER
                        $scope.userHomeDirDisplay = PAGE.homeDir + "/";
                        $scope.navigateMethod = "input";
                        $scope.dirContentsPanelOpen = true;
                        $scope.backupsPanelOpen = true;
                        $scope.currentDirectory = "/";
                        $scope.homeDir = "/";
                        $scope.noMetadataMessage = "";
                        $scope.isPathInputEmpty = true;

                        $scope.directoryContentsMeta = directoryContentsTable.getMetadata();
                        $scope.backupsMeta = backupsTable.getMetadata();
                        $scope.doesContentExistInfo = LOCALE.maketext("When you restore a backup, the system will overwrite existing files and restore deleted files.");
                        $scope.findByPathInfo = LOCALE.maketext("Enter the exact path to the file or directory that you wish to restore.");
                        $scope.actions = {
                            loadingUI: true,
                            loadingData: false,
                            loadingBackups: false
                        };
                        getDirectoryContentsPagination(paginationComponent);
                    }
                    init();
                }
            ]
        );

        return controller;
    }
);
Back to Directory File Manager