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_name: page_params.realm_name,
|
||||||
realm_org_type: page_params.realm_org_type,
|
realm_org_type: page_params.realm_org_type,
|
||||||
realm_available_video_chat_providers: page_params.realm_available_video_chat_providers,
|
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_rating_options: page_params.giphy_rating_options,
|
||||||
giphy_api_key_empty: page_params.giphy_api_key === "",
|
giphy_api_key_empty: page_params.giphy_api_key === "",
|
||||||
realm_description: page_params.realm_description,
|
realm_description: page_params.realm_description,
|
||||||
|
|||||||
@@ -59,6 +59,11 @@ let uppy;
|
|||||||
export function get_compose_upload_object() {
|
export function get_compose_upload_object() {
|
||||||
return uppy;
|
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() {
|
export function compute_show_video_chat_button() {
|
||||||
const available_providers = page_params.realm_available_video_chat_providers;
|
const available_providers = page_params.realm_available_video_chat_providers;
|
||||||
if (page_params.realm_video_chat_provider === available_providers.disabled.id) {
|
if (page_params.realm_video_chat_provider === available_providers.disabled.id) {
|
||||||
@@ -67,7 +72,7 @@ export function compute_show_video_chat_button() {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
page_params.realm_video_chat_provider === available_providers.jitsi_meet.id &&
|
page_params.realm_video_chat_provider === available_providers.jitsi_meet.id &&
|
||||||
!page_params.jitsi_server_url
|
!get_jitsi_server_url()
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -90,7 +95,7 @@ export function compute_show_audio_chat_button() {
|
|||||||
const available_providers = page_params.realm_available_video_chat_providers;
|
const available_providers = page_params.realm_available_video_chat_providers;
|
||||||
if (
|
if (
|
||||||
(available_providers.jitsi_meet &&
|
(available_providers.jitsi_meet &&
|
||||||
page_params.jitsi_server_url &&
|
get_jitsi_server_url() &&
|
||||||
page_params.realm_video_chat_provider === available_providers.jitsi_meet.id) ||
|
page_params.realm_video_chat_provider === available_providers.jitsi_meet.id) ||
|
||||||
(available_providers.zoom &&
|
(available_providers.zoom &&
|
||||||
page_params.realm_video_chat_provider === available_providers.zoom.id)
|
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 {
|
} else {
|
||||||
// TODO: Use `new URL` to generate the URLs here.
|
// TODO: Use `new URL` to generate the URLs here.
|
||||||
const video_call_id = util.random_int(100000000000000, 999999999999999);
|
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) {
|
if (is_audio_call) {
|
||||||
insert_audio_call_url(
|
insert_audio_call_url(
|
||||||
video_call_link + "#config.startWithVideoMuted=true",
|
video_call_link + "#config.startWithVideoMuted=true",
|
||||||
|
|||||||
@@ -232,6 +232,7 @@ export function dispatch_normal_event(event) {
|
|||||||
signup_notifications_stream_id: noop,
|
signup_notifications_stream_id: noop,
|
||||||
emails_restricted_to_domains: noop,
|
emails_restricted_to_domains: noop,
|
||||||
video_chat_provider: compose.update_audio_and_video_chat_button_display,
|
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,
|
giphy_rating: giphy.update_giphy_rating,
|
||||||
waiting_period_threshold: noop,
|
waiting_period_threshold: noop,
|
||||||
want_advertise_in_communities_directory: 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() {
|
function set_video_chat_provider_dropdown() {
|
||||||
const chat_provider_id = page_params.realm_video_chat_provider;
|
const chat_provider_id = page_params.realm_video_chat_provider;
|
||||||
$("#id_realm_video_chat_provider").val(chat_provider_id);
|
$("#id_realm_video_chat_provider").val(chat_provider_id);
|
||||||
|
|
||||||
|
set_jitsi_server_url_dropdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
function set_giphy_rating_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":
|
case "realm_video_chat_provider":
|
||||||
set_video_chat_provider_dropdown();
|
set_video_chat_provider_dropdown();
|
||||||
break;
|
break;
|
||||||
|
case "realm_jitsi_server_url":
|
||||||
|
set_jitsi_server_url_dropdown();
|
||||||
|
break;
|
||||||
case "realm_message_retention_days":
|
case "realm_message_retention_days":
|
||||||
case "message_retention_days":
|
case "message_retention_days":
|
||||||
set_message_retention_setting_dropdown(sub);
|
set_message_retention_setting_dropdown(sub);
|
||||||
@@ -888,6 +952,8 @@ export function get_input_element_value(input_elem, input_type) {
|
|||||||
}
|
}
|
||||||
case "time-limit":
|
case "time-limit":
|
||||||
return get_time_limit_setting_value($input_elem);
|
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":
|
case "message-retention-setting":
|
||||||
return get_message_retention_setting_value($input_elem);
|
return get_message_retention_setting_value($input_elem);
|
||||||
case "dropdown-list-widget":
|
case "dropdown-list-widget":
|
||||||
@@ -1003,6 +1069,9 @@ export function check_property_changed(elem, for_realm_default_settings, sub) {
|
|||||||
case "message_retention_days":
|
case "message_retention_days":
|
||||||
proposed_val = get_message_retention_setting_value($elem, false);
|
proposed_val = get_message_retention_setting_value($elem, false);
|
||||||
break;
|
break;
|
||||||
|
case "realm_jitsi_server_url":
|
||||||
|
proposed_val = get_jitsi_server_url_setting_value($elem, false);
|
||||||
|
break;
|
||||||
case "realm_default_language":
|
case "realm_default_language":
|
||||||
proposed_val = $(
|
proposed_val = $(
|
||||||
"#org-notifications .language_selection_widget .language_selection_button span",
|
"#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;
|
return setting_value <= MAX_CUSTOM_TIME_LIMIT_SETTING_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
function enable_or_disable_save_button($subsection_elem) {
|
function is_valid_url(jitsi_url) {
|
||||||
const time_limit_settings = [...$subsection_elem.find(".time-limit-setting")];
|
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;
|
let disable_save_btn = false;
|
||||||
for (const setting_elem of time_limit_settings) {
|
for (const setting_elem of time_limit_settings) {
|
||||||
const $dropdown_elem = $(setting_elem).find("select");
|
const $dropdown_elem = $(setting_elem).find("select");
|
||||||
@@ -1245,6 +1329,20 @@ function enable_or_disable_save_button($subsection_elem) {
|
|||||||
break;
|
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);
|
$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");
|
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) => {
|
$("#id_realm_message_retention_days").on("change", (e) => {
|
||||||
const message_retention_setting_dropdown_value = e.target.value;
|
const message_retention_setting_dropdown_value = e.target.value;
|
||||||
change_element_block_display_property(
|
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;
|
padding: 4px 6px;
|
||||||
color: hsl(0deg 0% 33%);
|
color: hsl(0deg 0% 33%);
|
||||||
border: 1px solid hsl(0deg 0% 80%);
|
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,
|
#profile-settings,
|
||||||
#edit-user-form {
|
#edit-user-form {
|
||||||
.custom_user_field {
|
.custom_user_field {
|
||||||
|
|||||||
@@ -114,6 +114,32 @@
|
|||||||
<option value='{{this.id}}'>{{this.name}}</option>
|
<option value='{{this.id}}'>{{this.name}}</option>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</select>
|
</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>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<label for="realm_giphy_rating" class="dropdown-title">
|
<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.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);
|
handler(ev);
|
||||||
assert.ok(!called);
|
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);
|
handler(ev);
|
||||||
// video link ids consist of 15 random digits
|
// video link ids consist of 15 random digits
|
||||||
const video_link_regex =
|
let video_link_regex =
|
||||||
/\[translated: Join video call\.]\(https:\/\/meet.jit.si\/\d{15}#config.startWithVideoMuted=false\)/;
|
/\[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.ok(called);
|
||||||
assert.match(syntax_to_insert, video_link_regex);
|
assert.match(syntax_to_insert, video_link_regex);
|
||||||
})();
|
})();
|
||||||
@@ -252,7 +270,7 @@ test("test_video_chat_button_toggle enabled", ({override}) => {
|
|||||||
override(upload, "feature_check", () => {});
|
override(upload, "feature_check", () => {});
|
||||||
|
|
||||||
page_params.realm_video_chat_provider = realm_available_video_chat_providers.jitsi_meet.id;
|
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();
|
compose.initialize();
|
||||||
assert.equal($("#below-compose-content .video_link").visible(), true);
|
assert.equal($("#below-compose-content .video_link").visible(), true);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user