Viewing File: /usr/local/cpanel/whostmgr/docroot/templates/cpanel_customization/views/jupiter/logoController.js

/*
# cpanel - whostmgr/docroot/templates/cpanel_customization/views/jupiter/logoController.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
*/

/* jshint -W100 */

define(
    [
        "lodash",
        "angular",
        "cjt/util/locale",
        "app/constants",
        "cjt/directives/autoFocus",
        "cjt/decorators/growlDecorator",
        "app/directives/fileUpload",
        "app/services/customizeService",
        "app/services/savedService",
    ],
    function(_, angular, LOCALE, CONSTANTS) {
        "use strict";

        var module = angular.module("customize.views.logoController", [
            "customize.services.customizeService",
            "customize.directives.fileUpload",
            "customize.services.savedService",
        ]);

        var controller = module.controller(
            "logoController", [
                "$scope",
                "customizeService",
                "savedService",
                "growl",
                "growlMessages",
                "PAGE",
                function($scope, customizeService, savedService, growl, growlMessages, PAGE) {
                    $scope.saving = false;

                    // Load the prefetched data from the PAGE object.
                    var lightLogo = PAGE.data.jupiter.brand.logo.forLightBackground;
                    var darkLogo = PAGE.data.jupiter.brand.logo.forDarkBackground;
                    var description = PAGE.data.jupiter.brand.logo.description;

                    /**
                     * @typedef FileModel
                     * @property {string} filename - name of the file to display
                     * @property {string} data - base 64 encoded file contents
                     * @property {boolean} saved - true if the file has been saved to the backend, false otherwise.
                     * @property {string} name - name of the property
                     */

                    /**
                     * @typedef LogosModel
                     * @property {FileModel} forLightBackground - storage for the logo use on light backgrounds.
                     * @property {FileModel} forDarkBackground - storage for the logo used on dark backgrounds.
                     * @property {string} description - description for use with the logos as the title property.
                     */
                    $scope.model = {
                        forLightBackground: {
                            data: lightLogo ? CONSTANTS.EMBEDDED_SVG + lightLogo : "",
                            filename: lightLogo ? "logo-light.svg" : "",
                            saved: !!lightLogo,
                            name: "forLightBackground",
                        },
                        forDarkBackground: {
                            data: darkLogo ? CONSTANTS.EMBEDDED_SVG + darkLogo : "",
                            filename: darkLogo ? "logo-dark.svg" : "",
                            saved: !!darkLogo,
                            name: "forDarkBackground",
                        },
                        description: description || "",
                    };

                    $scope.MAX_FILE_SIZE = CONSTANTS.MAX_FILE_SIZE;
                    $scope.LOCALE = LOCALE;

                    // Watch for changes
                    $scope.$watch("model.forLightBackground", function() {
                        savedService.update("logos", $scope.customization.$dirty);
                    }, true);

                    $scope.$watch("model.forDarkBackground", function() {
                        savedService.update("logos", $scope.customization.$dirty);
                    }, true);

                    $scope.$watch("model.description", function() {
                        savedService.update("logos", $scope.customization.$dirty);
                    }, false);

                    /**
                     * @typedef backgroundColors
                     * @property {string} primaryDark - the background color the logo in full screen.
                     * @property {string} primaryLight - the background color for the logo in mobile.
                     */
                    $scope.backgroundColors = {
                        primaryDark: PAGE.data.jupiter.brand.colors.primary || CONSTANTS.DEFAULT_PRIMARY_DARK,

                        // NOTE: There does not seem to be an override for mobile background for the logo
                        primaryLight: CONSTANTS.DEFAULT_PRIMARY_LIGHT,
                    };

                    /**
                     * Save the logo data from the tab.
                     *
                     * @param {FormController} $formCtrl
                     */
                    $scope.save = function($formCtrl) {
                        growlMessages.destroyAllMessages();

                        if (!$formCtrl.$valid) {
                            growl.error(LOCALE.maketext("The current customization is invalid."));
                            return;
                        }

                        if ($scope.saving) {
                            growl.warning(LOCALE.maketext("The system is busy. Try again once the current operation is complete."));
                            return;
                        }

                        $scope.saving = true;

                        var forDarkBackground = $scope.model.forDarkBackground.data;
                        if (forDarkBackground) {
                            forDarkBackground = forDarkBackground.replace(CONSTANTS.DATA_URL_PREFIX_REGEX, "");
                        }
                        var forLightBackground = $scope.model.forLightBackground.data;
                        if (forLightBackground) {
                            forLightBackground = forLightBackground.replace(CONSTANTS.DATA_URL_PREFIX_REGEX, "");
                        }

                        customizeService.update({
                            brand: {
                                logo: {
                                    forLightBackground: forLightBackground,
                                    forDarkBackground: forDarkBackground,
                                    description: $scope.model.description,
                                },
                            },
                        }).then(function(update) {
                            if (forDarkBackground) {
                                $scope.model.forDarkBackground.filename = "logo-dark.svg";
                                $scope.model.forDarkBackground.saved = true;

                                // Update the initial data
                                PAGE.data.jupiter.brand.logo.forDarkBackground = forDarkBackground;
                            }
                            if (forLightBackground) {
                                $scope.model.forLightBackground.filename = "logo-light.svg";
                                $scope.model.forLightBackground.saved = true;

                                // Update the initial data
                                PAGE.data.jupiter.brand.logo.forLightBackground = forLightBackground;
                            }

                            // Update the initial data
                            PAGE.data.jupiter.brand.logo.description = $scope.model.description;

                            $formCtrl.$setPristine();
                            savedService.update("logos", false);

                            growl.success(LOCALE.maketext("The system successfully updated the logos."));
                        }).catch(function(error) {
                            growl.error(LOCALE.maketext("The system failed to update your logos."));
                        }).finally(function() {
                            $scope.saving = false;
                        });
                    };

                    /**
                     * Evaluate the state of the inputs and update the $pristine state of the form.
                     *
                     * NOTE:
                     * angular.js does not reevalute the form.$isPristine flag when the child inputs
                     * are set to pristine individually. We must loop over the list of controls ourselves
                     * and the set this property.
                     * @param {FormController} $formCtrl
                     */
                    var updateFormState = function($formCtrl) {
                        var controls = ["file_upload_logo_dark_file", "file_upload_logo_light_file", "icon_description"];
                        var isPristine = true; // Assume pristine, unless there is evidence otherwise.
                        controls.forEach(function(inputName) {
                            if ($formCtrl[inputName].$dirty) {
                                isPristine = false;
                            }
                        });
                        if (isPristine) {
                            $formCtrl.$setPristine();
                        }
                    };

                    /**
                     * Reset the logo to a pristine state after a delete before saving.
                     *
                     * @param {FormController} $formCtrl
                     * @param {string} which
                     */
                    $scope.reset = function($formCtrl, which) {
                        growlMessages.destroyAllMessages();
                        switch (which) {
                            case "forDarkBackground":
                                $formCtrl.file_upload_logo_dark_file.$setPristine();
                                break;
                            case "forLightBackground":
                                $formCtrl.file_upload_logo_light_file.$setPristine();
                                break;
                        }
                        updateFormState($formCtrl);
                        savedService.update("logos", $formCtrl.$dirty);
                    };

                    /**
                     * Remove the specific logo from the
                     * @param {FormController} $formCtrl
                     * @param {string} which - the name of the image field to delete
                     */
                    $scope.delete = function($formCtrl, which) {
                        growlMessages.destroyAllMessages();

                        if ($scope.saving) {
                            growl.warning(LOCALE.maketext("The system is busy. Try again once the current operation is complete."));
                            return;
                        }

                        $scope.saving = true;
                        return customizeService.delete("brand.logo." + which)
                            .then(function(update) {
                                $scope.model[which].saved = false;
                                $scope.model[which].data = "";
                                $scope.model[which].filename = "";

                                // Update the initial data
                                PAGE.data.jupiter.brand.logo[which] = "";

                                // Reset the part of the form that was persisted.
                                switch (which) {
                                    case "forDarkBackground":
                                        $formCtrl.file_upload_logo_dark_file.$setPristine();
                                        break;
                                    case "forLightBackground":
                                        $formCtrl.file_upload_logo_light_file.$setPristine();
                                        break;
                                }
                                savedService.update("logos", $formCtrl.$dirty);

                                growl.success(LOCALE.maketext("The system successfully removed the logo."));
                            })
                            .catch(function(error) {
                                growl.error(LOCALE.maketext("The system failed to remove the logo."));
                            })
                            .finally(function() {
                                $scope.saving = false;
                            });
                    };
                },
            ]
        );

        return controller;
    }
);
Back to Directory File Manager