mirror of https://github.com/zulip/zulip.git
bot-settings: Add modal to generate Integration URL.
Fixes part of #25976.
This commit is contained in:
parent
bd631c4424
commit
9cde3abd4d
|
@ -0,0 +1,9 @@
|
|||
Generate the URL for your integration by clicking the **link** (<i
|
||||
class="fa fa-link"></i>) icon on the profile card for the bot you
|
||||
created.
|
||||
|
||||
{% if all_event_types is defined %}
|
||||
|
||||
{!event-filtering-instruction.md!}
|
||||
|
||||
{% endif %}
|
|
@ -8,6 +8,7 @@ import render_bot_settings_tip from "../templates/settings/bot_settings_tip.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 render_generate_integration_url_modal from "../templates/settings/generate_integration_url_modal.hbs";
|
||||
|
||||
import * as avatar from "./avatar";
|
||||
import * as bot_data from "./bot_data";
|
||||
|
@ -20,10 +21,12 @@ import {page_params} from "./page_params";
|
|||
import * as people from "./people";
|
||||
import * as settings_config from "./settings_config";
|
||||
import * as settings_users from "./settings_users";
|
||||
import * as stream_data from "./stream_data";
|
||||
import {show_copied_confirmation} from "./tippyjs";
|
||||
import * as ui_report from "./ui_report";
|
||||
import * as user_profile from "./user_profile";
|
||||
|
||||
const INCOMING_WEBHOOK_BOT_TYPE = 2;
|
||||
const OUTGOING_WEBHOOK_BOT_TYPE = "3";
|
||||
const EMBEDDED_BOT_TYPE = "4";
|
||||
export let bot_owner_dropdown_widget;
|
||||
|
@ -77,6 +80,7 @@ export function render_bots() {
|
|||
avatar_url: elem.avatar_url,
|
||||
api_key: elem.api_key,
|
||||
is_active: elem.is_active,
|
||||
is_incoming_webhook_bot: elem.bot_type === INCOMING_WEBHOOK_BOT_TYPE,
|
||||
zuliprc: "zuliprc", // Most browsers do not allow filename starting with `.`
|
||||
});
|
||||
user_owns_an_active_bot = user_owns_an_active_bot || elem.is_active;
|
||||
|
@ -356,6 +360,7 @@ export function show_edit_bot_info_modal(user_id, $container) {
|
|||
bot_avatar_url: bot.avatar_url,
|
||||
owner_full_name,
|
||||
current_bot_owner: bot.bot_owner_id,
|
||||
is_incoming_webhook_bot: bot.bot_type === INCOMING_WEBHOOK_BOT_TYPE,
|
||||
});
|
||||
$container.append(html_body);
|
||||
let avatar_widget;
|
||||
|
@ -504,9 +509,158 @@ export function show_edit_bot_info_modal(user_id, $container) {
|
|||
}
|
||||
confirm_bot_deactivation(bot_id, handle_confirm, true);
|
||||
});
|
||||
|
||||
$("#bot-edit-form").on("click", ".generate_url_for_integration", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const current_bot_data = bot_data.get(bot.user_id);
|
||||
show_generate_integration_url_modal(current_bot_data.api_key);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function show_generate_integration_url_modal(api_key) {
|
||||
const default_url_message = $t_html({defaultMessage: "Integration URL will appear here."});
|
||||
const streams = stream_data.subscribed_subs();
|
||||
const direct_messages_option = {
|
||||
name: $t_html({defaultMessage: "Direct message to me"}),
|
||||
unique_id: "",
|
||||
is_direct_message: true,
|
||||
};
|
||||
const html_body = render_generate_integration_url_modal({
|
||||
default_url_message,
|
||||
max_topic_length: page_params.max_topic_length,
|
||||
});
|
||||
|
||||
function generate_integration_url_post_render() {
|
||||
let selected_integration = "";
|
||||
let stream_input_dropdown_widget;
|
||||
|
||||
const $integration_input = $("#integration-input");
|
||||
const $override_topic = $("#integration-url-override-topic");
|
||||
const $topic_input = $("#integration-url-topic-input");
|
||||
const $integration_url = $("#generate-integration-url-modal .integration-url");
|
||||
const $dialog_submit_button = $("#generate-integration-url-modal .dialog_submit_button");
|
||||
|
||||
$dialog_submit_button.prop("disabled", true);
|
||||
|
||||
new ClipboardJS("#generate-integration-url-modal .dialog_submit_button", {
|
||||
text() {
|
||||
return $integration_url.text();
|
||||
},
|
||||
}).on("success", (e) => {
|
||||
show_copied_confirmation(e.trigger);
|
||||
});
|
||||
|
||||
$integration_input
|
||||
.typeahead({
|
||||
items: 5,
|
||||
fixed: true,
|
||||
source: () =>
|
||||
page_params.realm_incoming_webhook_bots.map((bot) => bot.display_name),
|
||||
updater(item) {
|
||||
selected_integration = page_params.realm_incoming_webhook_bots.find(
|
||||
(bot) => bot.display_name === item,
|
||||
).name;
|
||||
return item;
|
||||
},
|
||||
})
|
||||
.on("input", function () {
|
||||
const current_value = $(this).val();
|
||||
if (current_value === "") {
|
||||
selected_integration = "";
|
||||
}
|
||||
});
|
||||
|
||||
$override_topic.on("change", function () {
|
||||
const checked = $(this).prop("checked");
|
||||
$topic_input.parent().toggleClass("hide", !checked);
|
||||
});
|
||||
|
||||
$("#generate-integration-url-modal .integration-url-parameter").on("change input", () => {
|
||||
update_url();
|
||||
});
|
||||
|
||||
function update_url() {
|
||||
if (selected_integration === "") {
|
||||
$integration_url.text(default_url_message);
|
||||
$dialog_submit_button.prop("disabled", true);
|
||||
return;
|
||||
}
|
||||
|
||||
const stream_name = stream_input_dropdown_widget.value();
|
||||
const topic_name = $topic_input.val();
|
||||
|
||||
const params = new URLSearchParams({api_key});
|
||||
if (stream_name !== "") {
|
||||
params.set("stream", stream_name);
|
||||
if (topic_name !== "") {
|
||||
params.set("topic", topic_name);
|
||||
}
|
||||
}
|
||||
|
||||
const realm_url = page_params.realm_uri;
|
||||
const base_url = `${realm_url}/api/v1/external/`;
|
||||
$integration_url.text(`${base_url}${selected_integration}?${params}`);
|
||||
$dialog_submit_button.prop("disabled", false);
|
||||
}
|
||||
|
||||
stream_input_dropdown_widget = new dropdown_widget.DropdownWidget({
|
||||
widget_name: "integration-url-stream",
|
||||
get_options: get_options_for_stream_dropdown_widget,
|
||||
item_click_callback,
|
||||
$events_container: $("#generate-integration-url-modal"),
|
||||
tippy_props: {
|
||||
placement: "bottom-start",
|
||||
},
|
||||
default_id: direct_messages_option.unique_id,
|
||||
unique_id_type: dropdown_widget.DATA_TYPES.STRING,
|
||||
});
|
||||
stream_input_dropdown_widget.setup();
|
||||
|
||||
function get_options_for_stream_dropdown_widget() {
|
||||
const options = [
|
||||
direct_messages_option,
|
||||
...streams.map((stream) => ({
|
||||
name: stream.name,
|
||||
unique_id: stream.name,
|
||||
stream,
|
||||
})),
|
||||
];
|
||||
return options;
|
||||
}
|
||||
|
||||
function item_click_callback(event, dropdown) {
|
||||
stream_input_dropdown_widget.render();
|
||||
$(".integration-url-stream-wrapper").trigger("input");
|
||||
const user_selected_option = stream_input_dropdown_widget.value();
|
||||
if (user_selected_option === direct_messages_option.unique_id) {
|
||||
$override_topic.prop("checked", false).prop("disabled", true);
|
||||
$override_topic.closest(".input-group").addClass("control-label-disabled");
|
||||
$topic_input.val("");
|
||||
} else {
|
||||
$override_topic.prop("disabled", false);
|
||||
$override_topic.closest(".input-group").removeClass("control-label-disabled");
|
||||
}
|
||||
$override_topic.trigger("change");
|
||||
|
||||
dropdown.hide();
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
dialog_widget.launch({
|
||||
html_heading: $t_html({defaultMessage: "Generate URL for an integration"}),
|
||||
html_body,
|
||||
id: "generate-integration-url-modal",
|
||||
html_submit_button: $t_html({defaultMessage: "Copy URL"}),
|
||||
html_exit_button: $t_html({defaultMessage: "Close"}),
|
||||
on_click() {},
|
||||
post_render: generate_integration_url_post_render,
|
||||
});
|
||||
}
|
||||
|
||||
export function set_up() {
|
||||
$("#download_botserverrc").on("click", function () {
|
||||
const OUTGOING_WEBHOOK_BOT_TYPE_INT = 3;
|
||||
|
@ -610,6 +764,13 @@ export function set_up() {
|
|||
user_profile.show_user_profile(bot, "user-profile-streams-tab");
|
||||
});
|
||||
|
||||
$("#active_bots_list").on("click", "button.open-generate-integration-url-modal", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const api_key = $(e.currentTarget).attr("data-api-key");
|
||||
show_generate_integration_url_modal(api_key);
|
||||
});
|
||||
|
||||
const clipboard = new ClipboardJS("#copy_zuliprc", {
|
||||
text(trigger) {
|
||||
const $bot_info = $(trigger).closest(".bot-information-box").find(".bot_info");
|
||||
|
|
|
@ -874,6 +874,7 @@
|
|||
.grey-box,
|
||||
.white-box,
|
||||
.stream-email,
|
||||
#generate-integration-url-modal .integration-url,
|
||||
#settings_page .settings-header,
|
||||
#settings_page .sidebar li.active,
|
||||
#settings_page .sidebar-wrapper .tab-container,
|
||||
|
|
|
@ -869,6 +869,10 @@ input[type="checkbox"] {
|
|||
.purple {
|
||||
color: hsl(278deg 62% 68%);
|
||||
}
|
||||
|
||||
.steel-blue {
|
||||
color: hsl(207deg 44% 49%);
|
||||
}
|
||||
}
|
||||
|
||||
.bot-information-box {
|
||||
|
@ -2017,3 +2021,33 @@ $option_title_width: 180px;
|
|||
0 0 8px hsl(206deg 80% 62% / 60%);
|
||||
}
|
||||
}
|
||||
|
||||
#generate-integration-url-modal {
|
||||
.inline {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.integration-url {
|
||||
font-family: "Source Code Pro", monospace;
|
||||
padding: 10px;
|
||||
font-size: 0.85rem;
|
||||
border: 1px solid hsl(0deg 0% 87%);
|
||||
border-radius: 4px;
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.integration-url-stream-wrapper .dropdown_widget_value {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.integration-url-stream-wrapper .dropdown-widget-button {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
#stream-not-specified-notice {
|
||||
margin-top: -10px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
<button type="submit" class="btn open_bots_subscribed_streams tippy-zulip-delayed-tooltip" data-tippy-content="{{t 'Subscribed streams' }}" data-user-id="{{user_id}}">
|
||||
<i class="fa fa-hashtag purple" aria-hidden="true"></i>
|
||||
</button>
|
||||
{{#if is_incoming_webhook_bot}}
|
||||
<button type="submit" class="btn open-generate-integration-url-modal tippy-zulip-delayed-tooltip" data-tippy-content="{{t 'Generate URL for an integration'}}" data-api-key="{{api_key}}">
|
||||
<i class="fa fa-link steel-blue" aria-hidden="true"></i>
|
||||
</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -42,6 +42,13 @@
|
|||
<div><label for="edit_bot_avatar_file" generated="true" class="edit_bot_avatar_error text-error"></label></div>
|
||||
</div>
|
||||
</form>
|
||||
{{#if is_incoming_webhook_bot}}
|
||||
<div class="input-group new-style">
|
||||
<button class="button rounded generate_url_for_integration">
|
||||
{{t 'Generate URL for an integration' }}
|
||||
</button>
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="input-group new-style">
|
||||
<button class="button rounded btn-danger deactivate_bot_button">
|
||||
{{t 'Deactivate bot' }}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<div class="new-style">
|
||||
<div class="input-group">
|
||||
<label for="integration-input">{{t "Integration"}}</label>
|
||||
<input type="text" id="integration-input" class="modal_text_input integration-url-parameter" autocomplete="off"/>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<div class="integration-url-stream-wrapper integration-url-parameter">
|
||||
{{> ../dropdown_widget_with_label
|
||||
widget_name="integration-url-stream"
|
||||
label=(t "Where to send notifications")}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group control-label-disabled">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="integration-url-override-topic" class="integration-url-parameter" disabled/>
|
||||
<span></span>
|
||||
</label>
|
||||
<label class="inline" for="integration-url-override-topic">
|
||||
{{t "Send all notifications to a single topic"}}
|
||||
</label>
|
||||
</div>
|
||||
<div class="input-group hide">
|
||||
<label for="integration-url-topic-input">{{t "Topic"}}</label>
|
||||
<input type="text" id="integration-url-topic-input" class="modal_text_input integration-url-parameter" maxlength="{{ max_topic_length }}" />
|
||||
</div>
|
||||
<hr />
|
||||
<p class="integration-url-header">{{t "URL for your integration"}}</p>
|
||||
<div class="integration-url">
|
||||
{{default_url_message}}
|
||||
</div>
|
||||
</div>
|
Loading…
Reference in New Issue