mirror of
https://github.com/zulip/zulip.git
synced 2025-11-11 09:27:43 +00:00
org_settings: Add frontend support for realm_jitsi_server_url.
This commit adds a dropdown and custom input element to set the `realm_jitsi_server_url` when the video call provider is Jitsi. This allows organization administrators to add a custom Jitsi server as the organization's video call provider. Fixes #17914. Co-authored-by: Gaurav Pandey <gauravguitarrocks@gmail.com>
This commit is contained in:
@@ -99,6 +99,7 @@ export function build_page() {
|
||||
realm_name: page_params.realm_name,
|
||||
realm_org_type: page_params.realm_org_type,
|
||||
realm_available_video_chat_providers: page_params.realm_available_video_chat_providers,
|
||||
server_jitsi_server_url: page_params.server_jitsi_server_url,
|
||||
giphy_rating_options: page_params.giphy_rating_options,
|
||||
giphy_api_key_empty: page_params.giphy_api_key === "",
|
||||
realm_description: page_params.realm_description,
|
||||
|
||||
@@ -59,6 +59,11 @@ let uppy;
|
||||
export function get_compose_upload_object() {
|
||||
return uppy;
|
||||
}
|
||||
|
||||
function get_jitsi_server_url() {
|
||||
return page_params.realm_jitsi_server_url ?? page_params.server_jitsi_server_url;
|
||||
}
|
||||
|
||||
export function compute_show_video_chat_button() {
|
||||
const available_providers = page_params.realm_available_video_chat_providers;
|
||||
if (page_params.realm_video_chat_provider === available_providers.disabled.id) {
|
||||
@@ -67,7 +72,7 @@ export function compute_show_video_chat_button() {
|
||||
|
||||
if (
|
||||
page_params.realm_video_chat_provider === available_providers.jitsi_meet.id &&
|
||||
!page_params.jitsi_server_url
|
||||
!get_jitsi_server_url()
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@@ -90,7 +95,7 @@ export function compute_show_audio_chat_button() {
|
||||
const available_providers = page_params.realm_available_video_chat_providers;
|
||||
if (
|
||||
(available_providers.jitsi_meet &&
|
||||
page_params.jitsi_server_url &&
|
||||
get_jitsi_server_url() &&
|
||||
page_params.realm_video_chat_provider === available_providers.jitsi_meet.id) ||
|
||||
(available_providers.zoom &&
|
||||
page_params.realm_video_chat_provider === available_providers.zoom.id)
|
||||
@@ -940,7 +945,7 @@ function generate_and_insert_audio_or_video_call_link($target_element, is_audio_
|
||||
} else {
|
||||
// TODO: Use `new URL` to generate the URLs here.
|
||||
const video_call_id = util.random_int(100000000000000, 999999999999999);
|
||||
const video_call_link = page_params.jitsi_server_url + "/" + video_call_id;
|
||||
const video_call_link = get_jitsi_server_url() + "/" + video_call_id;
|
||||
if (is_audio_call) {
|
||||
insert_audio_call_url(
|
||||
video_call_link + "#config.startWithVideoMuted=true",
|
||||
|
||||
@@ -232,6 +232,7 @@ export function dispatch_normal_event(event) {
|
||||
signup_notifications_stream_id: noop,
|
||||
emails_restricted_to_domains: noop,
|
||||
video_chat_provider: compose.update_audio_and_video_chat_button_display,
|
||||
jitsi_server_url: compose.update_audio_and_video_chat_button_display,
|
||||
giphy_rating: giphy.update_giphy_rating,
|
||||
waiting_period_threshold: noop,
|
||||
want_advertise_in_communities_directory: noop,
|
||||
|
||||
@@ -266,9 +266,70 @@ function set_realm_waiting_period_setting() {
|
||||
);
|
||||
}
|
||||
|
||||
function is_video_chat_provider_jitsi_meet() {
|
||||
const video_chat_provider_id = Number.parseInt($("#id_realm_video_chat_provider").val(), 10);
|
||||
const jitsi_meet_id = page_params.realm_available_video_chat_providers.jitsi_meet.id;
|
||||
return video_chat_provider_id === jitsi_meet_id;
|
||||
}
|
||||
|
||||
function get_jitsi_server_url_setting_value($input_elem, for_api_data = true) {
|
||||
// If the video chat provider dropdown is not set to Jitsi, we return
|
||||
// `realm_jitsi_server_url` to indicate that the property remains unchanged.
|
||||
// This ensures the appropriate state of the save button and prevents the
|
||||
// addition of the `jitsi_server_url` in the API data.
|
||||
if (!is_video_chat_provider_jitsi_meet()) {
|
||||
return page_params.realm_jitsi_server_url;
|
||||
}
|
||||
|
||||
const select_elem_val = $input_elem.val();
|
||||
if (select_elem_val === "server_default") {
|
||||
if (!for_api_data) {
|
||||
return null;
|
||||
}
|
||||
return JSON.stringify("default");
|
||||
}
|
||||
|
||||
const $custom_input_elem = $("#id_realm_jitsi_server_url_custom_input");
|
||||
if (!for_api_data) {
|
||||
return $custom_input_elem.val();
|
||||
}
|
||||
return JSON.stringify($custom_input_elem.val());
|
||||
}
|
||||
|
||||
function update_jitsi_server_url_custom_input(dropdown_val) {
|
||||
const custom_input = "id_realm_jitsi_server_url_custom_input";
|
||||
change_element_block_display_property(custom_input, dropdown_val === "custom");
|
||||
|
||||
if (dropdown_val !== "custom") {
|
||||
return;
|
||||
}
|
||||
|
||||
const $custom_input_elem = $(`#${CSS.escape(custom_input)}`);
|
||||
$custom_input_elem.val(page_params.realm_jitsi_server_url);
|
||||
}
|
||||
|
||||
function set_jitsi_server_url_dropdown() {
|
||||
if (!is_video_chat_provider_jitsi_meet()) {
|
||||
$("#realm_jitsi_server_url_setting").hide();
|
||||
return;
|
||||
}
|
||||
|
||||
$("#realm_jitsi_server_url_setting").show();
|
||||
|
||||
let dropdown_val = "server_default";
|
||||
if (page_params.realm_jitsi_server_url) {
|
||||
dropdown_val = "custom";
|
||||
}
|
||||
|
||||
$("#id_realm_jitsi_server_url").val(dropdown_val);
|
||||
update_jitsi_server_url_custom_input(dropdown_val);
|
||||
}
|
||||
|
||||
function set_video_chat_provider_dropdown() {
|
||||
const chat_provider_id = page_params.realm_video_chat_provider;
|
||||
$("#id_realm_video_chat_provider").val(chat_provider_id);
|
||||
|
||||
set_jitsi_server_url_dropdown();
|
||||
}
|
||||
|
||||
function set_giphy_rating_dropdown() {
|
||||
@@ -712,6 +773,9 @@ export function discard_property_element_changes(elem, for_realm_default_setting
|
||||
case "realm_video_chat_provider":
|
||||
set_video_chat_provider_dropdown();
|
||||
break;
|
||||
case "realm_jitsi_server_url":
|
||||
set_jitsi_server_url_dropdown();
|
||||
break;
|
||||
case "realm_message_retention_days":
|
||||
case "message_retention_days":
|
||||
set_message_retention_setting_dropdown(sub);
|
||||
@@ -888,6 +952,8 @@ export function get_input_element_value(input_elem, input_type) {
|
||||
}
|
||||
case "time-limit":
|
||||
return get_time_limit_setting_value($input_elem);
|
||||
case "jitsi-server-url-setting":
|
||||
return get_jitsi_server_url_setting_value($input_elem);
|
||||
case "message-retention-setting":
|
||||
return get_message_retention_setting_value($input_elem);
|
||||
case "dropdown-list-widget":
|
||||
@@ -1003,6 +1069,9 @@ export function check_property_changed(elem, for_realm_default_settings, sub) {
|
||||
case "message_retention_days":
|
||||
proposed_val = get_message_retention_setting_value($elem, false);
|
||||
break;
|
||||
case "realm_jitsi_server_url":
|
||||
proposed_val = get_jitsi_server_url_setting_value($elem, false);
|
||||
break;
|
||||
case "realm_default_language":
|
||||
proposed_val = $(
|
||||
"#org-notifications .language_selection_widget .language_selection_button span",
|
||||
@@ -1212,8 +1281,23 @@ function check_maximum_valid_value($custom_input_elem, property_name) {
|
||||
return setting_value <= MAX_CUSTOM_TIME_LIMIT_SETTING_VALUE;
|
||||
}
|
||||
|
||||
function enable_or_disable_save_button($subsection_elem) {
|
||||
const time_limit_settings = [...$subsection_elem.find(".time-limit-setting")];
|
||||
function is_valid_url(jitsi_url) {
|
||||
const url_pattern = /^(https?:\/\/)/;
|
||||
return url_pattern.test(jitsi_url);
|
||||
}
|
||||
|
||||
function should_disable_save_button_for_jitsi_server_url_setting() {
|
||||
if (!is_video_chat_provider_jitsi_meet()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const $dropdown_elem = $("#id_realm_jitsi_server_url");
|
||||
const $custom_input_elem = $("#id_realm_jitsi_server_url_custom_input");
|
||||
|
||||
return $dropdown_elem.val() === "custom" && !is_valid_url($custom_input_elem.val());
|
||||
}
|
||||
|
||||
function should_disable_save_button_for_time_limit_settings(time_limit_settings) {
|
||||
let disable_save_btn = false;
|
||||
for (const setting_elem of time_limit_settings) {
|
||||
const $dropdown_elem = $(setting_elem).find("select");
|
||||
@@ -1245,6 +1329,20 @@ function enable_or_disable_save_button($subsection_elem) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return disable_save_btn;
|
||||
}
|
||||
|
||||
function enable_or_disable_save_button($subsection_elem) {
|
||||
const time_limit_settings = [...$subsection_elem.find(".time-limit-setting")];
|
||||
|
||||
let disable_save_btn = false;
|
||||
if (time_limit_settings.length) {
|
||||
disable_save_btn = should_disable_save_button_for_time_limit_settings(time_limit_settings);
|
||||
} else if ($subsection_elem.attr("id") === "org-other-settings") {
|
||||
disable_save_btn = should_disable_save_button_for_jitsi_server_url_setting();
|
||||
}
|
||||
|
||||
$subsection_elem.find(".subsection-changes-save button").prop("disabled", disable_save_btn);
|
||||
}
|
||||
|
||||
@@ -1453,6 +1551,15 @@ export function build_page() {
|
||||
update_custom_value_input("realm_message_content_delete_limit_seconds");
|
||||
});
|
||||
|
||||
$("#id_realm_video_chat_provider").on("change", () => {
|
||||
set_jitsi_server_url_dropdown();
|
||||
});
|
||||
|
||||
$("#id_realm_jitsi_server_url").on("change", (e) => {
|
||||
const dropdown_val = e.target.value;
|
||||
update_jitsi_server_url_custom_input(dropdown_val);
|
||||
});
|
||||
|
||||
$("#id_realm_message_retention_days").on("change", (e) => {
|
||||
const message_retention_setting_dropdown_value = e.target.value;
|
||||
change_element_block_display_property(
|
||||
|
||||
@@ -1508,7 +1508,8 @@ $option_title_width: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
.time-limit-custom-input {
|
||||
.time-limit-custom-input,
|
||||
.realm_jitsi_server_url_custom_input {
|
||||
padding: 4px 6px;
|
||||
color: hsl(0deg 0% 33%);
|
||||
border: 1px solid hsl(0deg 0% 80%);
|
||||
@@ -1525,6 +1526,16 @@ $option_title_width: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
#realm_jitsi_server_url_setting {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 15px;
|
||||
|
||||
.jitsi_server_url_custom_input_label {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
#profile-settings,
|
||||
#edit-user-form {
|
||||
.custom_user_field {
|
||||
|
||||
@@ -114,6 +114,32 @@
|
||||
<option value='{{this.id}}'>{{this.name}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
|
||||
<div class="dependent-settings-block" id="realm_jitsi_server_url_setting">
|
||||
<div>
|
||||
<label for="id_realm_jitsi_server_url" class="dropdown-title">
|
||||
{{t "Jitsi server URL" }}
|
||||
</label>
|
||||
<select name="realm_jitsi_server_url" id="id_realm_jitsi_server_url" class="setting-widget prop-element settings_select bootstrap-focus-style" data-setting-widget-type="jitsi-server-url-setting">
|
||||
{{#if server_jitsi_server_url}}
|
||||
<option value="server_default">
|
||||
{{#tr}}{server_jitsi_server_url} (default){{/tr}}
|
||||
</option>
|
||||
{{else}}
|
||||
<option value="server_default">{{t 'Disabled' }}</option>
|
||||
{{/if}}
|
||||
<option value="custom">{{t 'Custom URL' }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="id_realm_jitsi_server_url_custom_input" class="jitsi_server_url_custom_input_label">
|
||||
{{t 'URL' }}
|
||||
</label>
|
||||
<input type="text" id="id_realm_jitsi_server_url_custom_input" autocomplete="off"
|
||||
name="realm_jitsi_server_url_custom_input" class="realm_jitsi_server_url_custom_input settings_url_input"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="realm_giphy_rating" class="dropdown-title">
|
||||
|
||||
@@ -119,15 +119,33 @@ test("videos", ({override}) => {
|
||||
|
||||
page_params.realm_video_chat_provider = realm_available_video_chat_providers.jitsi_meet.id;
|
||||
|
||||
page_params.jitsi_server_url = null;
|
||||
page_params.realm_jitsi_server_url = null;
|
||||
page_params.server_jitsi_server_url = null;
|
||||
handler(ev);
|
||||
assert.ok(!called);
|
||||
|
||||
page_params.jitsi_server_url = "https://meet.jit.si";
|
||||
page_params.realm_jitsi_server_url = null;
|
||||
page_params.server_jitsi_server_url = "https://server.example.com";
|
||||
handler(ev);
|
||||
// video link ids consist of 15 random digits
|
||||
const video_link_regex =
|
||||
/\[translated: Join video call\.]\(https:\/\/meet.jit.si\/\d{15}#config.startWithVideoMuted=false\)/;
|
||||
let video_link_regex =
|
||||
/\[translated: Join video call\.]\(https:\/\/server.example.com\/\d{15}#config.startWithVideoMuted=false\)/;
|
||||
assert.ok(called);
|
||||
assert.match(syntax_to_insert, video_link_regex);
|
||||
|
||||
page_params.realm_jitsi_server_url = "https://realm.example.com";
|
||||
page_params.server_jitsi_server_url = null;
|
||||
handler(ev);
|
||||
video_link_regex =
|
||||
/\[translated: Join video call\.]\(https:\/\/realm.example.com\/\d{15}#config.startWithVideoMuted=false\)/;
|
||||
assert.ok(called);
|
||||
assert.match(syntax_to_insert, video_link_regex);
|
||||
|
||||
page_params.realm_jitsi_server_url = "https://realm.example.com";
|
||||
page_params.server_jitsi_server_url = "https://server.example.com";
|
||||
handler(ev);
|
||||
video_link_regex =
|
||||
/\[translated: Join video call\.]\(https:\/\/realm.example.com\/\d{15}#config.startWithVideoMuted=false\)/;
|
||||
assert.ok(called);
|
||||
assert.match(syntax_to_insert, video_link_regex);
|
||||
})();
|
||||
@@ -252,7 +270,7 @@ test("test_video_chat_button_toggle enabled", ({override}) => {
|
||||
override(upload, "feature_check", () => {});
|
||||
|
||||
page_params.realm_video_chat_provider = realm_available_video_chat_providers.jitsi_meet.id;
|
||||
page_params.jitsi_server_url = "https://meet.jit.si";
|
||||
page_params.realm_jitsi_server_url = "https://meet.jit.si";
|
||||
compose.initialize();
|
||||
assert.equal($("#below-compose-content .video_link").visible(), true);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user