<commit_before>import ClipboardJS from "clipboard";
import $ from "jquery";

import render_settings_deactivation_bot_modal from "../templates/confirm_dialog/confirm_deactivate_bot.hbs";
import render_add_new_bot_form from "../templates/settings/add_new_bot_form.hbs";
import render_bot_avatar_row from "../templates/settings/bot_avatar_row.hbs";
import render_edit_bot_form from "../templates/settings/edit_bot_form.hbs";
import render_settings_edit_embedded_bot_service from "../templates/settings/edit_embedded_bot_service.hbs";
import render_settings_edit_outgoing_webhook_service from "../templates/settings/edit_outgoing_webhook_service.hbs";

import * as avatar from "./avatar";
import * as blueslip from "./blueslip";
import * as bot_data from "./bot_data";
import * as channel from "./channel";
import {csrf_token} from "./csrf";
import * as dialog_widget from "./dialog_widget";
import {DropdownListWidget} from "./dropdown_list_widget";
import {$t, $t_html} from "./i18n";
import {page_params} from "./page_params";
import * as people from "./people";
import * as settings_config from "./settings_config";
import * as ui_report from "./ui_report";
import * as user_profile from "./user_profile";

const OUTGOING_WEBHOOK_BOT_TYPE = "3";
const EMBEDDED_BOT_TYPE = "4";

export function hide_errors() {
    $("#bot_table_error").hide();
    $(".bot_error").hide();
}

const focus_tab = {
    active_bots_tab() {
        $("#bots_lists_navbar .active").removeClass("active");
        $("#bots_lists_navbar .active-bots-tab").addClass("active");
        $("#active_bots_list").show();
        $("#inactive_bots_list").hide();
        hide_errors();
    },
    inactive_bots_tab() {
        $("#bots_lists_navbar .active").removeClass("active");
        $("#bots_lists_navbar .inactive-bots-tab").addClass("active");
        $("#active_bots_list").hide();
        $("#inactive_bots_list").show();
        hide_errors();
    },
};

export function get_bot_info_div(bot_id) {
    const sel = `.bot_info[data-user-id="${CSS.escape(bot_id)}"]`;
    return $(sel).expectOne();
}

export function bot_error(bot_id, xhr) {
    const $bot_info = get_bot_info_div(bot_id);
    const $bot_error_div = $bot_info.find(".bot_error");
    $bot_error_div.text(JSON.parse(xhr.responseText).msg);
    $bot_error_div.show();
    const $bot_box = $bot_info.closest(".bot-information-box");
    $bot_box.scrollTop($bot_box[0].scrollHeight - $bot_box[0].clientHeight);
}

function add_bot_row(info) {
    const $row = $(render_bot_avatar_row(info));
    if (info.is_active) {
        $("#active_bots_list").append($row);
    } else {
        $("#inactive_bots_list").append($row);
    }
}

function is_local_part(value) {
    // Adapted from Django's EmailValidator
    return /^[\w!#$%&'*+/=?^`{|}~-]+(\.[\w!#$%&'*+/=?^`{|}~-]+)*$/i.test(value);
}

export function type_id_to_string(type_id) {
    return page_params.bot_types.find((bot_type) => bot_type.type_id === type_id).name;
}

export function render_bots() {
    $("#active_bots_list").empty();
    $("#inactive_bots_list").empty();

    const all_bots_for_current_user = bot_data.get_all_bots_for_current_user();
    let user_owns_an_active_bot = false;

    for (const elem of all_bots_for_current_user) {
        add_bot_row({
            name: elem.full_name,
            email: elem.email,
            user_id: elem.user_id,
            type: type_id_to_string(elem.bot_type),
            avatar_url: elem.avatar_url,
            api_key: elem.api_key,
            is_active: elem.is_active,
            zuliprc: "zuliprc", // Most browsers do not allow filename starting with `.`
        });
        user_owns_an_active_bot = user_owns_an_active_bot || elem.is_active;
    }
}

export function generate_zuliprc_uri(bot_id) {
    const bot = bot_data.get(bot_id);
    const data = generate_zuliprc_content(bot);
    return encode_zuliprc_as_uri(data);
}

export function encode_zuliprc_as_uri(zuliprc) {
    return "data:application/octet-stream;charset=utf-8," + encodeURIComponent(zuliprc);
}

export function generate_zuliprc_content(bot) {
    let token;
    // For outgoing webhooks, include the token in the zuliprc.
    // It's needed for authenticating to the Botserver.
    if (bot.bot_type === 3) {
        token = bot_data.get_services(bot.user_id)[0].token;
    }
    return (
        "[api]" +
        "\nemail=" +
        bot.email +
        "\nkey=" +
        bot.api_key +
        "\nsite=" +
        page_params.realm_uri +
        (token === undefined ? "" : "\ntoken=" + token) +
        // Some tools would not work in files without a trailing new line.
        "\n"
    );
}

export function generate_botserverrc_content(email, api_key, token) {
    return (
        "[]" +
        "\nemail=" +
        email +
        "\nkey=" +
        api_key +
        "\nsite=" +
        page_params.realm_uri +
        "\ntoken=" +
        token +
        "\n"
    );
}

export const bot_creation_policy_values = {
    admins_only: {
        code: 3,
        description: $t({defaultMessage: "Admins"}),
    },
    everyone: {
        code: 1,
        description: $t({defaultMessage: "Admins, moderators and members"}),
    },
    restricted: {
        code: 2,
        description: $t({
            defaultMessage: "Admins, moderators and members, but only admins can add generic bots",
        }),
    },
};

export function can_create_new_bots() {
    if (page_params.is_admin) {
        return true;
    }

    if (page_params.is_guest) {
        return false;
    }

    return page_params.realm_bot_creation_policy !== bot_creation_policy_values.admins_only.code;
}

export function update_bot_settings_tip() {
    const permission_type = bot_creation_policy_values;
    const current_permission = page_params.realm_bot_creation_policy;
    let tip_text;
    if (current_permission === permission_type.admins_only.code) {
        tip_text = $t({
            defaultMessage: "Only organization administrators can add bots to this organization.",
        });
    } else if (current_permission === permission_type.restricted.code) {
        tip_text = $t({defaultMessage: "Only organization administrators can add generic bots."});
    } else {
        tip_text = $t({defaultMessage: "Anyone in this organization can add bots."});
    }
    $(".bot-settings-tip").text(tip_text);
}

export function update_bot_permissions_ui() {
    update_bot_settings_tip();
    hide_errors();
    $("#id_realm_bot_creation_policy").val(page_params.realm_bot_creation_policy);
}

export function add_a_new_bot() {
    const html_body = render_add_new_bot_form({
        bot_types: page_params.bot_types,
        realm_embedded_bots: page_params.realm_embedded_bots,
        realm_bot_domain: page_params.realm_bot_domain,
    });

    let create_avatar_widget;

    function create_a_new_bot() {
        const bot_type = $("#create_bot_type :selected").val();
        const full_name = $("#create_bot_name").val();
        const short_name = $("#create_bot_short_name").val() || $("#create_bot_short_name").text();
        const payload_url = $("#create_payload_url").val();
        const interface_type = $("#create_interface_type").val();
        const service_name = $("#select_service_name :selected").val();
        const formData = new FormData();

        formData.append("csrfmiddlewaretoken", csrf_token);
        formData.append("bot_type", bot_type);
        formData.append("full_name", full_name);
        formData.append("short_name", short_name);<commit_msg>bots: Live update add new bot button on changing bot_creation_policy.<commit_after>import ClipboardJS from "clipboard";
import $ from "jquery";

import render_settings_deactivation_bot_modal from "../templates/confirm_dialog/confirm_deactivate_bot.hbs";
import render_add_new_bot_form from "../templates/settings/add_new_bot_form.hbs";
import render_bot_avatar_row from "../templates/settings/bot_avatar_row.hbs";
import render_edit_bot_form from "../templates/settings/edit_bot_form.hbs";
import render_settings_edit_embedded_bot_service from "../templates/settings/edit_embedded_bot_service.hbs";
import render_settings_edit_outgoing_webhook_service from "../templates/settings/edit_outgoing_webhook_service.hbs";

import * as avatar from "./avatar";
import * as blueslip from "./blueslip";
import * as bot_data from "./bot_data";
import * as channel from "./channel";
import {csrf_token} from "./csrf";
import * as dialog_widget from "./dialog_widget";
import {DropdownListWidget} from "./dropdown_list_widget";
import {$t, $t_html} from "./i18n";
import {page_params} from "./page_params";
import * as people from "./people";
import * as settings_config from "./settings_config";
import * as ui_report from "./ui_report";
import * as user_profile from "./user_profile";

const OUTGOING_WEBHOOK_BOT_TYPE = "3";
const EMBEDDED_BOT_TYPE = "4";

export function hide_errors() {
    $("#bot_table_error").hide();
    $(".bot_error").hide();
}

const focus_tab = {
    active_bots_tab() {
        $("#bots_lists_navbar .active").removeClass("active");
        $("#bots_lists_navbar .active-bots-tab").addClass("active");
        $("#active_bots_list").show();
        $("#inactive_bots_list").hide();
        hide_errors();
    },
    inactive_bots_tab() {
        $("#bots_lists_navbar .active").removeClass("active");
        $("#bots_lists_navbar .inactive-bots-tab").addClass("active");
        $("#active_bots_list").hide();
        $("#inactive_bots_list").show();
        hide_errors();
    },
};

export function get_bot_info_div(bot_id) {
    const sel = `.bot_info[data-user-id="${CSS.escape(bot_id)}"]`;
    return $(sel).expectOne();
}

export function bot_error(bot_id, xhr) {
    const $bot_info = get_bot_info_div(bot_id);
    const $bot_error_div = $bot_info.find(".bot_error");
    $bot_error_div.text(JSON.parse(xhr.responseText).msg);
    $bot_error_div.show();
    const $bot_box = $bot_info.closest(".bot-information-box");
    $bot_box.scrollTop($bot_box[0].scrollHeight - $bot_box[0].clientHeight);
}

function add_bot_row(info) {
    const $row = $(render_bot_avatar_row(info));
    if (info.is_active) {
        $("#active_bots_list").append($row);
    } else {
        $("#inactive_bots_list").append($row);
    }
}

function is_local_part(value) {
    // Adapted from Django's EmailValidator
    return /^[\w!#$%&'*+/=?^`{|}~-]+(\.[\w!#$%&'*+/=?^`{|}~-]+)*$/i.test(value);
}

export function type_id_to_string(type_id) {
    return page_params.bot_types.find((bot_type) => bot_type.type_id === type_id).name;
}

export function render_bots() {
    $("#active_bots_list").empty();
    $("#inactive_bots_list").empty();

    const all_bots_for_current_user = bot_data.get_all_bots_for_current_user();
    let user_owns_an_active_bot = false;

    for (const elem of all_bots_for_current_user) {
        add_bot_row({
            name: elem.full_name,
            email: elem.email,
            user_id: elem.user_id,
            type: type_id_to_string(elem.bot_type),
            avatar_url: elem.avatar_url,
            api_key: elem.api_key,
            is_active: elem.is_active,
            zuliprc: "zuliprc", // Most browsers do not allow filename starting with `.`
        });
        user_owns_an_active_bot = user_owns_an_active_bot || elem.is_active;
    }
}

export function generate_zuliprc_uri(bot_id) {
    const bot = bot_data.get(bot_id);
    const data = generate_zuliprc_content(bot);
    return encode_zuliprc_as_uri(data);
}

export function encode_zuliprc_as_uri(zuliprc) {
    return "data:application/octet-stream;charset=utf-8," + encodeURIComponent(zuliprc);
}

export function generate_zuliprc_content(bot) {
    let token;
    // For outgoing webhooks, include the token in the zuliprc.
    // It's needed for authenticating to the Botserver.
    if (bot.bot_type === 3) {
        token = bot_data.get_services(bot.user_id)[0].token;
    }
    return (
        "[api]" +
        "\nemail=" +
        bot.email +
        "\nkey=" +
        bot.api_key +
        "\nsite=" +
        page_params.realm_uri +
        (token === undefined ? "" : "\ntoken=" + token) +
        // Some tools would not work in files without a trailing new line.
        "\n"
    );
}

export function generate_botserverrc_content(email, api_key, token) {
    return (
        "[]" +
        "\nemail=" +
        email +
        "\nkey=" +
        api_key +
        "\nsite=" +
        page_params.realm_uri +
        "\ntoken=" +
        token +
        "\n"
    );
}

export const bot_creation_policy_values = {
    admins_only: {
        code: 3,
        description: $t({defaultMessage: "Admins"}),
    },
    everyone: {
        code: 1,
        description: $t({defaultMessage: "Admins, moderators and members"}),
    },
    restricted: {
        code: 2,
        description: $t({
            defaultMessage: "Admins, moderators and members, but only admins can add generic bots",
        }),
    },
};

export function can_create_new_bots() {
    if (page_params.is_admin) {
        return true;
    }

    if (page_params.is_guest) {
        return false;
    }

    return page_params.realm_bot_creation_policy !== bot_creation_policy_values.admins_only.code;
}

export function update_bot_settings_tip() {
    const permission_type = bot_creation_policy_values;
    const current_permission = page_params.realm_bot_creation_policy;
    let tip_text;
    if (current_permission === permission_type.admins_only.code) {
        tip_text = $t({
            defaultMessage: "Only organization administrators can add bots to this organization.",
        });
    } else if (current_permission === permission_type.restricted.code) {
        tip_text = $t({defaultMessage: "Only organization administrators can add generic bots."});
    } else {
        tip_text = $t({defaultMessage: "Anyone in this organization can add bots."});
    }
    $(".bot-settings-tip").text(tip_text);
}

function update_add_bot_button() {
    if (can_create_new_bots()) {
        $("#bot-settings .add-a-new-bot").show();
        $("#admin-bot-list .add-a-new-bot").show();
    } else {
        $("#bot-settings .add-a-new-bot").hide();
        $("#admin-bot-list .add-a-new-bot").hide();
    }
}

export function update_bot_permissions_ui() {
    update_bot_settings_tip();
    hide_errors();
    update_add_bot_button();
    $("#id_realm_bot_creation_policy").val(page_params.realm_bot_creation_policy);
}

export function add_a_new_bot() {
    const html_body = render_add_new_bot_form({
        bot_types: page_params.bot_types,
        realm_embedded_bots: page_params.realm_embedded_bots,
        realm_bot_domain: page_params.realm_bot_domain,
    });

    let create_avatar_widget;

    function create_a_new_bot() {
        const bot_type = $("#create_bot_type :selected").val();
        const full_name = $("#create_bot_name").val();
        const short_name = $("#create_bot_short_name").val() || $("#create_bot_short_name").text();
        const payload_url = $("#create_payload_url").val();
        const interface_type = $("#create_interface_type").val();
        const service_name = $("#select_service_name :selected").val();
        const formData = new FormData();

        formData.append("csrfmiddlewaretoken", csrf_token);
        formData.append("bot_type", bot_type);
        formData.append("full_name", full_name);
        formData.append("short_name", short_name);
{'fraction_non_alphanumeric': 0.14146721151975092, 'fraction_numerical': 0.0015567230978789648, 'mean_word_length': 3.3652321630804076, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6481614', 'n_tokens_mistral': 5125, 'n_tokens_neox': 5071, 'n_words': 928}