mirror of https://github.com/zulip/zulip.git
bot-url: Add event filtering UI to generate bot URL modal.
Adds an option to the generate bot URL modal to filter for events that will trigger notifications. This option is conditionally displayed when only `all_event_types` is defined for the selected integration. If selected, the URL will display all events by default. There are "check all" and "uncheck all" buttons to easily include or remove all the events from the URL. Fixes #27628.
This commit is contained in:
parent
a61c06c425
commit
fbcf31c9e0
|
@ -3,6 +3,7 @@ import $ from "jquery";
|
||||||
import type {Instance} from "tippy.js";
|
import type {Instance} from "tippy.js";
|
||||||
|
|
||||||
import render_generate_integration_url_modal from "../templates/settings/generate_integration_url_modal.hbs";
|
import render_generate_integration_url_modal from "../templates/settings/generate_integration_url_modal.hbs";
|
||||||
|
import render_integration_events from "../templates/settings/integration_events.hbs";
|
||||||
|
|
||||||
import {show_copied_confirmation} from "./copied_tooltip";
|
import {show_copied_confirmation} from "./copied_tooltip";
|
||||||
import * as dialog_widget from "./dialog_widget";
|
import * as dialog_widget from "./dialog_widget";
|
||||||
|
@ -39,6 +40,7 @@ export function show_generate_integration_url_modal(api_key: string): void {
|
||||||
const $topic_input = $<HTMLInputElement>("input#integration-url-topic-input");
|
const $topic_input = $<HTMLInputElement>("input#integration-url-topic-input");
|
||||||
const $integration_url = $("#generate-integration-url-modal .integration-url");
|
const $integration_url = $("#generate-integration-url-modal .integration-url");
|
||||||
const $dialog_submit_button = $("#generate-integration-url-modal .dialog_submit_button");
|
const $dialog_submit_button = $("#generate-integration-url-modal .dialog_submit_button");
|
||||||
|
const $show_integration_events = $("#show-integration-events");
|
||||||
|
|
||||||
$dialog_submit_button.prop("disabled", true);
|
$dialog_submit_button.prop("disabled", true);
|
||||||
$("#integration-url-stream_widget").prop("disabled", true);
|
$("#integration-url-stream_widget").prop("disabled", true);
|
||||||
|
@ -57,11 +59,33 @@ export function show_generate_integration_url_modal(api_key: string): void {
|
||||||
$topic_input.parent().toggleClass("hide", !checked);
|
$topic_input.parent().toggleClass("hide", !checked);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$show_integration_events.on("change", () => {
|
||||||
|
$("#integrations-event-container").toggleClass(
|
||||||
|
"hide",
|
||||||
|
!$show_integration_events.prop("checked"),
|
||||||
|
);
|
||||||
|
update_url(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on("change", "#integrations-event-container .integration-event", () => {
|
||||||
|
update_url();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#add-all-integration-events").on("click", () => {
|
||||||
|
$("#integrations-event-container .integration-event").prop("checked", true);
|
||||||
|
update_url();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#remove-all-integration-events").on("click", () => {
|
||||||
|
$("#integrations-event-container .integration-event").prop("checked", false);
|
||||||
|
update_url();
|
||||||
|
});
|
||||||
|
|
||||||
$("#generate-integration-url-modal .integration-url-parameter").on("change input", () => {
|
$("#generate-integration-url-modal .integration-url-parameter").on("change input", () => {
|
||||||
update_url();
|
update_url();
|
||||||
});
|
});
|
||||||
|
|
||||||
function update_url(): void {
|
function update_url(render_events = false): void {
|
||||||
selected_integration = integration_input_dropdown_widget.value()!.toString();
|
selected_integration = integration_input_dropdown_widget.value()!.toString();
|
||||||
if (selected_integration === default_integration_option.unique_id) {
|
if (selected_integration === default_integration_option.unique_id) {
|
||||||
$("#integration-url-stream_widget").prop("disabled", true);
|
$("#integration-url-stream_widget").prop("disabled", true);
|
||||||
|
@ -73,6 +97,35 @@ export function show_generate_integration_url_modal(api_key: string): void {
|
||||||
const stream_id = stream_input_dropdown_widget.value();
|
const stream_id = stream_input_dropdown_widget.value();
|
||||||
const topic_name = $topic_input.val()!;
|
const topic_name = $topic_input.val()!;
|
||||||
|
|
||||||
|
const selected_integration_data = realm.realm_incoming_webhook_bots.find(
|
||||||
|
(bot) => bot.name === selected_integration,
|
||||||
|
);
|
||||||
|
const all_event_types = selected_integration_data?.all_event_types;
|
||||||
|
|
||||||
|
if (all_event_types !== null) {
|
||||||
|
$("#integration-events-parameter").removeClass("hide");
|
||||||
|
} else {
|
||||||
|
$("#integration-events-parameter").addClass("hide");
|
||||||
|
$("#integrations-event-container").addClass("hide");
|
||||||
|
$("#integrations-event-options").empty();
|
||||||
|
$show_integration_events.prop("checked", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($show_integration_events.prop("checked") && render_events) {
|
||||||
|
const events_with_ids = all_event_types?.map((event) => {
|
||||||
|
const event_id = event.replaceAll(/\s+/g, "-");
|
||||||
|
return {
|
||||||
|
event,
|
||||||
|
event_id,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
events_with_ids?.sort((a, b) => a.event.localeCompare(b.event));
|
||||||
|
const events = render_integration_events({
|
||||||
|
events: events_with_ids,
|
||||||
|
});
|
||||||
|
$("#integrations-event-options").empty().append(events);
|
||||||
|
}
|
||||||
|
|
||||||
const params = new URLSearchParams({api_key});
|
const params = new URLSearchParams({api_key});
|
||||||
if (stream_id !== -1) {
|
if (stream_id !== -1) {
|
||||||
params.set("stream", stream_id!.toString());
|
params.set("stream", stream_id!.toString());
|
||||||
|
@ -80,13 +133,17 @@ export function show_generate_integration_url_modal(api_key: string): void {
|
||||||
params.set("topic", topic_name);
|
params.set("topic", topic_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const selected_events = set_events_param(params);
|
||||||
|
|
||||||
const realm_url = realm.realm_uri;
|
const realm_url = realm.realm_uri;
|
||||||
const base_url = `${realm_url}/api/v1/external/`;
|
const base_url = `${realm_url}/api/v1/external/`;
|
||||||
$integration_url.text(`${base_url}${selected_integration}?${params.toString()}`);
|
$integration_url.text(`${base_url}${selected_integration}?${params.toString()}`);
|
||||||
$dialog_submit_button.prop("disabled", false);
|
$dialog_submit_button.prop("disabled", false);
|
||||||
|
|
||||||
if ($override_topic.prop("checked") && topic_name === "") {
|
if (
|
||||||
|
($override_topic.prop("checked") && topic_name === "") ||
|
||||||
|
($show_integration_events.prop("checked") && !selected_events)
|
||||||
|
) {
|
||||||
$dialog_submit_button.prop("disabled", true);
|
$dialog_submit_button.prop("disabled", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,6 +231,26 @@ export function show_generate_integration_url_modal(api_key: string): void {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function set_events_param(params: URLSearchParams): boolean {
|
||||||
|
if (!$show_integration_events.prop("checked")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const $selected_integration_events = $(
|
||||||
|
"#integrations-event-container .integration-event:checked",
|
||||||
|
);
|
||||||
|
|
||||||
|
const selected_events = $selected_integration_events
|
||||||
|
.map(function () {
|
||||||
|
return $(this).val();
|
||||||
|
})
|
||||||
|
.get();
|
||||||
|
if (selected_events.length > 0) {
|
||||||
|
params.set("only_events", JSON.stringify(selected_events));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog_widget.launch({
|
dialog_widget.launch({
|
||||||
|
|
|
@ -482,3 +482,23 @@
|
||||||
border: 1px solid var(--color-hotkey-hint);
|
border: 1px solid var(--color-hotkey-hint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#generate-integration-url-modal {
|
||||||
|
#integrations-event-container {
|
||||||
|
.integration-all-events-buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin: 5px 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#integrations-event-options {
|
||||||
|
.integration-event-wrapper {
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.integration-event-name {
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,23 @@
|
||||||
<label for="integration-url-topic-input">{{t "Topic"}}</label>
|
<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 }}" />
|
<input type="text" id="integration-url-topic-input" class="modal_text_input integration-url-parameter" maxlength="{{ max_topic_length }}" />
|
||||||
</div>
|
</div>
|
||||||
|
<div id="integration-events-parameter" class="input-group hide">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" id="show-integration-events"/>
|
||||||
|
<span></span>
|
||||||
|
</label>
|
||||||
|
<label class="inline" for="show-integration-events">
|
||||||
|
{{t "Filter events that will trigger notifications?"}}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="input-group hide" id="integrations-event-container">
|
||||||
|
<label for="integrations-event-options">{{t "Events to include:"}}</label>
|
||||||
|
<div class="integration-all-events-buttons">
|
||||||
|
<button class="button rounded" id="add-all-integration-events">{{t "Check all"}}</button>
|
||||||
|
<button class="button rounded" id="remove-all-integration-events">{{t "Uncheck all"}}</button>
|
||||||
|
</div>
|
||||||
|
<div id="integrations-event-options"></div>
|
||||||
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
<p class="integration-url-header">{{t "URL for your integration"}}</p>
|
<p class="integration-url-header">{{t "URL for your integration"}}</p>
|
||||||
<div class="integration-url">
|
<div class="integration-url">
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
{{#each events }}
|
||||||
|
<div class="integration-event-wrapper">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" class="integration-event" id="{{this.event_id}}" checked=true
|
||||||
|
value="{{this.event}}" />
|
||||||
|
<span>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<label for="{{this.event_id}}" class="inline integration-event-name">
|
||||||
|
{{this.event}}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
Loading…
Reference in New Issue