Viewing File: /usr/local/cpanel/whostmgr/docroot/templates/setupcluster/page.js

/**
 * Page-specific Javascript for Set Up Cluster Configuration page.
 * @class SetupCluster
 */

/* global jQuery */
/* jshint -W100 */

(function() {

    /**
     * After successful link creation, adds row to table.
     *
     * @method addServerRow
     */
    var addServerRow = function(name, user, key) {

        // build new row
        var newRow = document.createElement("tr");
        newRow.className = "serverLink";
        newRow.setAttribute("data-server", name);
        var nameCell = document.createElement("td");
        nameCell.className = "serverName";
        nameCell.innerHTML = name;
        var userCell = document.createElement("td");
        userCell.className = "userName";
        userCell.innerHTML = user;
        var keyCell = document.createElement("td");
        keyCell.className = "hashValue";
        keyCell.innerHTML = key;
        var actionsCell = document.createElement("td");
        actionsCell.className = "actions text-right";
        actionsCell.innerHTML = "";
        var deleteBtn = document.createElement("button");
        deleteBtn.className = "deleteBtn btn-link";
        var documentDirection = document.documentElement.dir;
        if (documentDirection !== "rtl") {
            deleteBtn.className += " newRowIconHack";
        }
        deleteBtn.type = "button";
        var deleteIcon = document.createElement("span");
        deleteIcon.className = "glyphicon glyphicon-trash";
        deleteBtn.appendChild(deleteIcon);
        deleteBtn.title = LOCALE.maketext("Delete entry for “[_1]”.", name);

        actionsCell.appendChild(deleteBtn);
        var manageBtn = document.createElement("button");
        manageBtn.className = "manageBtn btn-link";
        if (documentDirection === "rtl") {
            manageBtn.className += " newRowIconHack";
        }
        manageBtn.type = "button";
        manageBtn.title = LOCALE.maketext("Edit key for “[_1]”.", name);
        var manageIcon = document.createElement("span");
        manageIcon.innerHTML = "";
        manageIcon.className = documentDirection === "rtl" ? "glyphicon glyphicon-chevron-left" : "glyphicon glyphicon-chevron-right";
        manageBtn.appendChild(manageIcon);

        actionsCell.appendChild(manageBtn);

        newRow.appendChild(nameCell);
        newRow.appendChild(userCell);
        newRow.appendChild(keyCell);
        newRow.appendChild(actionsCell);

        jQuery("#serverList tr:last").after(newRow);

        jQuery("#serverList tr:last td:last button.deleteBtn").on("click", confirmDelete);
        jQuery("#serverList tr:last td:last button.manageBtn").on("click", editServerLink);

        // add success highlight color to new row

        jQuery("#serverList tr:last").addClass("success");

        // set timer to remove success color after 4 seconds

        window.setTimeout(function() {
            jQuery("#serverList tr:last").removeClass("success");
        }, 4000);
    };

    /**
     * Attempts to create new server link based on editor values.
     *
     * @method addServer
     */
    var addServer = function() {
        if (validateEditorData("create")) {
            jQuery("#serverSaveChanges").prop("disabled", true);
            CPANEL.api({
                application: "whm",
                func: "add_configclusterserver",
                data: {
                    name: jQuery("#serverNameEditor").val(),
                    key: jQuery("#serverKeyEditor").val(),
                    user: jQuery("#serverUserEditor").val(),
                },
                callback: {
                    success: addLinkServerSuccess,
                    failure: addLinkServerFailure,
                },
            });
        }
    };

    /**
     * Attempts to create update an existing server link based on editor values.
     *
     * @method updateServer
     */
    var updateServer = function() {
        if (validateEditorData("update")) {
            CPANEL.api({
                application: "whm",
                func: "update_configclusterserver",
                data: {
                    name: jQuery("#serverNameEditor").val(),
                    user: jQuery("#serverUserEditor").val(),
                    key: jQuery("#serverKeyEditor").val(),
                },
                callback: {
                    success: function(args) {
                        if (args.cpanel_raw.metadata.result === 1) {
                            updateLinkServerSuccess(args);
                        } else {
                            updateLinkServerFailure(args);
                        }
                    },
                    failure: updateLinkServerFailure,
                },
            });
        }
    };

    /**
     * Clears the values in the editor fields so placeholders displayed correctly for add
     *
     * @method clearEditorFields
     */
    var clearEditorFields = function() {

        // clear the fields in the editor

        jQuery("#serverNameEditor").val("");
        jQuery("#serverKeyEditor").val("");
        jQuery("#serverUserEditor").val("");

        // make sure the Save button is enabled

        jQuery("#serverSaveChanges").prop("disabled", false);

        // set the key editor placeholder back to the default

        jQuery("#serverKeyEditor").attr("placeholder", LOCALE.maketext("Paste the server’s API token here."));
    };

    /**
     * Provides basic front-end validation for editor values.
     *
     * @param {String} mode The type of change being attempted (create|update).
     * @method validateEditorData
     */

    var validateEditorData = function(mode) {
        var isValid = true;
        var errorMsg = "";
        var serverName = jQuery("#serverNameEditor").val().trim();
        var serverKey = jQuery("#serverKeyEditor").val().trim();
        var serverUser = jQuery("#serverUserEditor").val().trim();

        // check to see if both fields are filled
        if (mode === "create" && (!serverName || !serverKey || !serverUser)) {
            errorMsg = LOCALE.maketext("The server name, username, and API token are required.");
            isValid = false;
        } else if (mode === "create" && (!CPANEL.validate.host(serverName) && !CPANEL.validate.ip(serverName))) {
            errorMsg = LOCALE.maketext("The server name must be a valid host name or ip address.");
            isValid = false;
        } else if (mode === "create" && !serverUser.match(/^[0-9a-zA-Z]+/)) {
            errorMsg = LOCALE.maketext("The username can only include alphanumeric characters.");
            isValid = false;
        } else if (mode !== "create" && !serverUser && !serverKey) {
            errorMsg = LOCALE.maketext("You must specify both a username and an API token.");
            isValid = false;
        } else if (mode !== "create" && serverUser && !serverUser.match(/^[0-9a-zA-Z]+/)) {
            errorMsg = LOCALE.maketext("The username can only include alphanumeric characters.");
            isValid = false;
        }

        if (errorMsg) {
            showFailureMessage(errorMsg);
        }

        return isValid;
    };

    /**
     * Displays a global success message alert
     *
     * @param {String} message The message to be displayed
     * @method showSuccessMessage
     */
    var showSuccessMessage = function(message) {

        // hide any existing failure messages
        hideFailureMessage();
        jQuery("#globalSuccessMessage").html(message);
        if (jQuery("#globalSuccessNotice").hasClass("hidden")) {
            jQuery("#globalSuccessNotice").removeClass("hidden");
        }
        window.setTimeout(function() {
            jQuery("#globalSuccessNotice").addClass("hidden");
        }, 7000);
    };

    /**
     * Displays a global failure message alert
     *
     * @param {String} message The message to be displayed
     * @method showFailureMessage
     */
    var showFailureMessage = function(message) {
        hideSuccessMessage();
        jQuery("#globalFailureMessage").html(message);
        jQuery("#globalFailureNotice").removeClass("hidden");
    };

    /**
     * Hide any existing success message.
     *
     * @method hideSuccessMessage
     */
    var hideSuccessMessage = function() {
        if (!jQuery("#globalSuccessNotice").hasClass("hidden")) {
            jQuery("#globalSuccessNotice").addClass("hidden");
        }
    };

    /**
     * Hide any existing failure message.
     *
     * @method hideFailureMessage
     */
    var hideFailureMessage = function() {
        if (!jQuery("#globalFailureNotice").hasClass("hidden")) {
            jQuery("#globalFailureNotice").addClass("hidden");
        }
    };

    /**
    * Updates the user interface when a link entry has been successfully updated
    *
    * @param {Object} args Data returned by API call
    * @method updateLinkServerSuccess
    */
    var updateLinkServerSuccess = function(args) {
        var serverName = args.cpanel_raw.metadata.name;

        showSuccessMessage(LOCALE.maketext("Link definition for server, [output,strong,_1], successfully updated.", serverName));

        // update the row in the table

        jQuery("tr[data-server=\"" + serverName + "\"] td.hashValue").html(args.cpanel_raw.metadata.signature);
        jQuery("tr[data-server=\"" + serverName + "\"] td.userName").html(args.cpanel_raw.metadata.user);

        hideEditor();

        clearEditorFields();
    };

    /**
    * Updates the user interface when a link entry has not been successfully updated
    *
    * @param {Object} args Data returned by API call
    * @method updateLinkServerFailure
    */
    var updateLinkServerFailure = function(args) {
        try {
            showFailureMessage(LOCALE.maketext("Link definition for server, [output,strong,_1], not updated.", args.cpanel_raw.metadata.name));
        } catch (err) {
            showFailureMessage(LOCALE.maketext("Link definition for server not updated."));
        }
    };


    /**
    * Updates the user interface when a new link entry has been successfully created
    *
    * @param {Object} args Data returned by API call
    * @method addLinkServerSuccess
    */
    var addLinkServerSuccess = function(args) {
        hideEditor();

        var callbackData = args.cpanel_raw.metadata;

        showSuccessMessage(LOCALE.maketext("Link to server, [output,strong,_1], successfully created.", callbackData.name));
        addServerRow(callbackData.name, callbackData.user, callbackData.signature);

        if (jQuery("tbody").children(".serverLink").length > 0 && !jQuery("#noLinksDefined").hasClass("hidden")) {
            jQuery("#noLinksDefined").addClass("hidden");
        }

        clearEditorFields();
    };

    /**
    * Updates the user interface when a new link entry has been successfully created
    *
    * @param {Object} args Data returned by API call
    * @method addLinkServerFailure
    */
    var addLinkServerFailure = function(args) {
        try {
            showFailureMessage(LOCALE.maketext("Unable to create link to server “[output,strong,_1]”.", args.cpanel_raw.metadata.name));
        } catch (err) {
            showFailureMessage(LOCALE.maketext("Unable to create link to server."));
        }
    };

    /**
    * Updates the user interface when a link entry has not been successfully deleted
    *
    * @param {Object} args Data returned by API call
    * @method deleteLinkServerFailure
    */
    var deleteLinkServerFailure = function(args) {
        try {
            showFailureMessage(LOCALE.maketext("Unable to delete link to server “[output,strong,_1]”.", args.cpanel_raw.metadata.name));
        } catch (err) {
            showFailureMessage(LOCALE.maketext("Unable to delete link to server."));
        }
        jQuery("#serverDeleteContinueBtn").prop("disabled", false);
    };

    /**
    * Prompts the user to confirm that he/she really wants to delete a server link
    *
    * @method confirmDelete
    */
    var confirmDelete = function() {
        var itemToDelete = jQuery(this).closest("tr").data("server");

        jQuery("#serverToDelete").val(itemToDelete);
        jQuery("#confirmMessage").html(LOCALE.maketext("Delete link to server “[output,strong,_1]”?", itemToDelete));

        var itemRow = jQuery("tr[data-server=\"" + itemToDelete + "\"]");
        var confirmRow = jQuery("#confirmDelete").detach();
        confirmRow.insertAfter(itemRow);

        toggleButtonStateForInlineModalAlert(true);

        itemRow.addClass("hidden");
        confirmRow.removeClass("hidden");
    };

    /**
    * Processes a delete server link request (after user confirmation)
    *
    * @method doDelete
    */
    var doDelete = function() {
        jQuery("#serverDeleteContinueBtn").prop("disabled", true);
        CPANEL.api({
            application: "whm",
            func: "delete_configclusterserver",
            data: {
                name: jQuery("#serverToDelete").val(),
            },
            callback: {
                success: function(args) {
                    if (args.cpanel_raw.metadata.result === 1) {
                        var serverName = args.cpanel_raw.metadata.name;
                        jQuery("tr[data-server=\"" + serverName + "\"]").remove();
                        jQuery("#tableAlerts").append(jQuery("#confirmDelete").detach());
                        var rowsLeft = jQuery("tbody").children(".serverLink").length;
                        var noLinksWarningIsHidden = jQuery("#noLinksDefined").hasClass("hidden");
                        if (rowsLeft === 0 && noLinksWarningIsHidden) {
                            jQuery("#noLinksDefined").removeClass("hidden");
                        }
                        toggleButtonStateForInlineModalAlert(false);
                        showSuccessMessage(LOCALE.maketext("Link to server, [output,strong,_1], successfully deleted.", serverName));
                        jQuery("#serverDeleteContinueBtn").prop("disabled", false);
                    } else {
                        deleteLinkServerFailure(args);
                    }
                },
                failure: deleteLinkServerFailure,
            },
        });
    };

    /**
    * Returns user interface to prior state (after user cancels a delete)
    *
    * @method cancelDelete
    */
    var cancelDelete = function() {
        var rowToRestore = jQuery("#serverToDelete").val();
        var alertRow = jQuery("#confirmDelete").detach();
        jQuery("#tableAlerts").append(alertRow);
        jQuery("#serverToDelete").val("");
        jQuery("tr[data-server=\"" + rowToRestore + "\"]").removeClass("hidden");
        toggleButtonStateForInlineModalAlert(false);
    };

    /**
     * Clears error message. Enables Save button.
     *
     * @method clearError
     */
    var clearError = function() {
        if (jQuery("#globalFailureMessage").html() !== "") {
            hideFailureMessage();
            jQuery("#globalFailureMessage").html("");
            jQuery("#serverSaveChanges").prop("disabled", false);
        }
    };


    /**
     * Shows link editor for adding and updating server links.
     *
     * @param {String} mode Which version of the editor to display (edit | add)
     * @method showEditor
     */
    var showEditor = function(mode) {

        jQuery("#serverSaveChanges").off("click");
        jQuery("#createBtnContainer").addClass("hidden");
        jQuery("#serverList").addClass("hidden");
        jQuery("#extraCreateButton").addClass("hidden");
        if (mode === "edit") {
            jQuery("#editServerHeadline").removeClass("hidden");
            jQuery("#addServerHeadline").addClass("hidden");
            jQuery("#serverSaveChanges").on("click", updateServer);
            jQuery("#serverNameEditor").prop("disabled", true);
        } else {
            jQuery("#editServerHeadline").addClass("hidden");
            jQuery("#addServerHeadline").removeClass("hidden");
            jQuery("#serverSaveChanges").on("click", addServer);
            jQuery("#serverUserEditor").val("root");
        }
        jQuery("#serverLinkEditor").removeClass("hidden");
        if (mode === "edit") {
            jQuery("#serverKeyEditor").focus();
        } else {
            jQuery("#serverNameEditor").focus();
        }
    };

    /**
     * Hides link editor and shows list again.
     *
     * @method hideEditor
     */
    var hideEditor = function() {
        jQuery("#serverLinkEditor").addClass("hidden");
        jQuery("#createBtnContainer").removeClass("hidden");
        jQuery("#serverList").removeClass("hidden");
        jQuery("#extraCreateButton").removeClass("hidden");
        jQuery("#serverNameEditor").prop("disabled", false);
    };

    /**
     * Disables/enables all user interface buttons except for those in the editor.
     * This prevents the application getting into a confusing state.
     *
     * @param {Boolean} disabled Determines which state buttons should reflect (true if you want buttons disabled)
     * @method toggleButtonStateForInlineModalAlert
     */
    var toggleButtonStateForInlineModalAlert = function(disabled) {

        if (disabled) {
            jQuery("#createBtn").attr("disabled", "disabled");
            jQuery("#createBtn2").attr("disabled", "disabled");
            jQuery(".deleteBtn").prop("disabled", disabled);
            jQuery(".manageBtn").prop("disabled", disabled);
            jQuery(".deleteBtn").addClass("disabled");
            jQuery(".manageBtn").addClass("disabled");
        } else {
            jQuery("#createBtn").removeAttr("disabled");
            jQuery("#createBtn2").removeAttr("disabled");
            jQuery(".deleteBtn").removeAttr("disabled");
            jQuery(".manageBtn").removeAttr("disabled");
            jQuery(".deleteBtn").removeClass("disabled");
            jQuery(".manageBtn").removeClass("disabled");
        }
    };

    /**
     * Shows editor populated with correct values for server in clicked row.
     *
     * @method editServerLink
     */
    var editServerLink = function() {
        var itemToEdit = jQuery(this).closest("tr").data("server");
        var scrambledKey = jQuery(this).closest("tr").children().filter(".hashValue").html();
        var userName = jQuery(this).closest("tr").children().filter(".userName").html();
        jQuery("#serverNameEditor").val(itemToEdit);
        jQuery("#serverUserEditor").attr("placeholder", userName);
        jQuery("#serverKeyEditor").attr("placeholder", LOCALE.maketext("Paste the replacement API token here. The current signature is: [_1]", scrambledKey.trim()));
        showEditor("edit");
    };

    /*
     * Initializes page-specific object.
     *
     * @method initialize
     */

    var initialize = function() {

        jQuery("#serverSaveChanges").on("click", addServer);

        jQuery(".deleteBtn").on("click", confirmDelete);

        jQuery("#goBack").on("click", function() {
            hideFailureMessage();
            hideSuccessMessage();
            hideEditor();
            clearEditorFields();
        });

        jQuery("#serverNameEditor").on("input", clearError);
        jQuery("#serverUserEditor").on("input", clearError);
        jQuery("#serverKeyEditor").on("input", clearError);

        jQuery("#createBtn").on("click", function() {
            showEditor("add");
        });

        jQuery("#createBtn2").on("click", function() {
            showEditor("add");
        });

        jQuery("#serverDeleteCancelBtn").on("click", cancelDelete);
        jQuery("#serverDeleteContinueBtn").on("click", doDelete);

        jQuery("#hideSuccessAlertBtn").on("click", function() {
            jQuery("#globalSuccessNotice").addClass("hidden");
        });

        jQuery("#hideFailureAlertBtn").on("click", function() {
            jQuery("#globalFailureNotice").addClass("hidden");
        });

        // Firefox seems to want to remember a bunch of
        // crap between reloads. What a pain.

        // force serverToDelete to empty string
        jQuery("#serverToDelete").val("");

        // clear the name and key fields in the editor
        clearEditorFields();

        // enable all buttons
        toggleButtonStateForInlineModalAlert(false);

        jQuery(".manageBtn").on("click", editServerLink);
    };

    jQuery(document).ready(initialize);
}());
Back to Directory File Manager