forked from External/greenlight
Merge v2.7-alpha (#1951)
* Fix wrong conditional (reported by LGTM) (#1477)
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Co-authored-by: Ahmad Farhat <ahmad.af.farhat@gmail.com>
* Bump rack from 2.2.2 to 2.2.3 (#1839)
Bumps [rack](https://github.com/rack/rack) from 2.2.2 to 2.2.3.
- [Release notes](https://github.com/rack/rack/releases)
- [Changelog](https://github.com/rack/rack/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rack/rack/compare/v2.2.2...2.2.3)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* [FIX] Unable to edit long recording names #1776 (#1780)
* Allow to set a filter for LDAP authentication
* [FIX] Unable to edit long recording names #1776
Co-authored-by: François Ménabé <francois.menabe@unistra.fr>
Co-authored-by: farhatahmad <ahmad.af.farhat@gmail.com>
* Desgin for Manage Users Tabs (#1777)
* Update _subtitle.html.erb
* Update _manage_users_tags.html.erb
* Update admins.scss
* Update _primary_themes.scss
* Update _manage_users_tags.html.erb
* Minor style changes to manage users (#1845)
* Maintenance banner moved to admin site (#1775)
* initial
* finish
* travis fixes
* travis again
* not required
* Co-authored-by: Tobias Fiebig <t.fiebig@tudelft.nl> (#1296)
Co-authored-by: Ahmad Farhat <ahmad.af.farhat@gmail.com>
* Enhance Room OpenGraph Metadata (#1601)
* Revert "Enhance Room OpenGraph Metadata (#1601)" (#1852)
This reverts commit 3b007c233a
.
* GRN2-xx: Tab title now displays the current page name (#1853)
* Tab title now displays the current page name
* Added page title for the rest of the pages
* Split Site Settings into 3 different tabs (#1858)
* Split Site Settings into 3 different tabs
* Fix copyright
* Added redirect to correct tab
* Make sure settings are displaying when they should
* Update en.yml (#1857)
* Build images for alpha branches (#1867)
* Upgraded jquery to latest version (#1896)
* Added favicon tag (#1898)
* Fixed XSS issue with role name (#1899)
* Update path for coloring redirect (#1908)
* Added a fourth section to the room uid (#1910)
* Fixed issue with insecure room sharing removal (#1914)
* Fixes typo (#1917)
Fixes typo: successfully was written incorrect.
* Fixed order of rooms in server rooms (#1915)
* Change default room sort to latest activity (#1919)
* GRN2-xx: Small changes/improvements to the recording settings (#1851)
* Small changes/improvements to the recording settings
* Replaced room warning with info flash
* Added global setting to enable/disable the recording consent feature
* Replace Legal with Terms (#1931)
* Added a more friendly OpenGraph description when invited to join a room (#1932)
* Fixed issue causing maintenance banner not to hide correctly (#1933)
* Hide recording menu and recording list when it is disabled (#1935)
* Hide recording menu and recording list when it is disabled
* Hide recording list when disabled
* GRN2-xx: Added an auto-refresh after 2 mins while waiting for room to start (#1947)
* Added an auto-refresh after 2 mins while waiting for room to start
* Fixed random issue with test case
* GRN2-xx: Added ability to preupload presentations to rooms (#1895)
* Added ability to preupload presentations to rooms (#1868)
* Added setting to site settings and allowed admins to change the presentation
* Added AWS S3 and GCS Storage ENV variables
* Added check to ensure file extension is correct
* Added icon to remove presentation
* Added testcases for preupload
* Add nginx redirect to solve issue with relative root
* Record title, instead of room name, in the popup (#1924)
* Update _public_recording_row.html.erb
* Update _recording_row.html.erb
Co-authored-by: Stefan Weil <sw@weilnetz.de>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: beckerr-rzht <beckerr@hochschule-trier.de>
Co-authored-by: François Ménabé <francois.menabe@unistra.fr>
Co-authored-by: MrKeksi <mrkeksi@users.noreply.github.com>
Co-authored-by: yanosz <yanosz@users.noreply.github.com>
Co-authored-by: Moritz Schlarb <moschlar@metalabs.de>
Co-authored-by: chronikum <34622984+chronikum@users.noreply.github.com>
Co-authored-by: Mitsutaka Sato <miztaka@honestyworks.jp>
Co-authored-by: hiroshisuga <45039819+hiroshisuga@users.noreply.github.com>
This commit is contained in:
BIN
app/assets/images/favicon.ico
Normal file
BIN
app/assets/images/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
@ -86,7 +86,11 @@ $(document).on('turbolinks:load', function(){
|
||||
})
|
||||
}
|
||||
else if(action == "site_settings"){
|
||||
loadColourSelectors()
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
// Only load the colour selectors if on the appearance tab
|
||||
if (urlParams.get("tab") == null || urlParams.get("tab") == "appearance") {
|
||||
loadColourSelectors()
|
||||
}
|
||||
}
|
||||
else if (action == "roles"){
|
||||
// Refreshes the new role modal
|
||||
@ -119,19 +123,30 @@ $(document).on('turbolinks:load', function(){
|
||||
// Change the branding image to the image provided
|
||||
function changeBrandingImage(path) {
|
||||
var url = $("#branding-url").val()
|
||||
$.post(path, {value: url})
|
||||
$.post(path, {value: url, tab: "appearance"})
|
||||
}
|
||||
|
||||
// Change the Legal URL to the one provided
|
||||
function changeLegalURL(path) {
|
||||
var url = $("#legal-url").val()
|
||||
$.post(path, {value: url})
|
||||
$.post(path, {value: url, tab: "administration"})
|
||||
}
|
||||
|
||||
// Change the Privacy Policy URL to the one provided
|
||||
function changePrivacyPolicyURL(path) {
|
||||
var url = $("#privpolicy-url").val()
|
||||
$.post(path, {value: url})
|
||||
$.post(path, {value: url, tab: "administration"})
|
||||
}
|
||||
|
||||
// Display the maintenance Banner
|
||||
function displayMaintenanceBanner(path) {
|
||||
var message = $("#maintenance-banner").val()
|
||||
$.post(path, {value: message, tab: "administration"})
|
||||
}
|
||||
|
||||
// Clear the maintenance Banner
|
||||
function clearMaintenanceBanner(path) {
|
||||
$.post(path, {value: "", tab: "administration"})
|
||||
}
|
||||
|
||||
function mergeUsers() {
|
||||
@ -234,13 +249,13 @@ function loadColourSelectors() {
|
||||
})
|
||||
|
||||
pickrLighten.on("save", (color, instance) => {
|
||||
$.post($("#coloring-path-lighten").val(), {value: color.toHEXA().toString()}).done(function() {
|
||||
$.post($("#coloring-path-lighten").val(), {value: color.toHEXA().toString(), tab: "appearance"}).done(function() {
|
||||
location.reload()
|
||||
});
|
||||
})
|
||||
|
||||
pickrDarken.on("save", (color, instance) => {
|
||||
$.post($("#coloring-path-darken").val(), {value: color.toHEXA().toString()}).done(function() {
|
||||
$.post($("#coloring-path-darken").val(), {value: color.toHEXA().toString(), tab: "appearance"}).done(function() {
|
||||
location.reload()
|
||||
});
|
||||
})
|
||||
|
@ -27,7 +27,7 @@
|
||||
// about supported directives.
|
||||
//
|
||||
//= require turbolinks
|
||||
//= require jquery
|
||||
//= require jquery3
|
||||
//= require tabler
|
||||
//= require tabler.plugins
|
||||
//= require jquery_ujs
|
||||
|
@ -26,9 +26,12 @@ $(document).on('turbolinks:load', function(){
|
||||
})
|
||||
|
||||
$("#maintenance-close").click(function(event) {
|
||||
//create a cookie that lasts 1 year
|
||||
var cookieDate = new Date();
|
||||
cookieDate.setFullYear(cookieDate.getFullYear() + 1); //1 year from now
|
||||
//create a cookie that lasts 1 day
|
||||
|
||||
var cookieDate = new Date()
|
||||
cookieDate.setDate(cookieDate.getDate() + 1) //1 day from now
|
||||
console.log("maintenance_window=" + $(event.target).data("date") + "; path=/; expires=" + cookieDate.toUTCString() + ";")
|
||||
|
||||
document.cookie = "maintenance_window=" + $(event.target).data("date") + "; path=/; expires=" + cookieDate.toUTCString() + ";"
|
||||
})
|
||||
})
|
||||
|
@ -48,6 +48,8 @@ $(document).on('turbolinks:load', function(){
|
||||
$("#create-room-block").click(function(){
|
||||
showCreateRoom(this)
|
||||
})
|
||||
|
||||
checkIfAutoJoin()
|
||||
}
|
||||
|
||||
// Autofocus on the Room Name label when creating a room only
|
||||
@ -129,6 +131,27 @@ $(document).on('turbolinks:load', function(){
|
||||
$("#user-list").append(listItem)
|
||||
}
|
||||
})
|
||||
|
||||
$("#presentation-upload").change(function(data) {
|
||||
var file = data.target.files[0]
|
||||
|
||||
// Check file type and size to make sure they aren't over the limit
|
||||
if (validFileUpload(file)) {
|
||||
$("#presentation-upload-label").text(file.name)
|
||||
} else {
|
||||
$("#invalid-file-type").show()
|
||||
$("#presentation-upload").val("")
|
||||
$("#presentation-upload-label").text($("#presentation-upload-label").data("placeholder"))
|
||||
}
|
||||
})
|
||||
|
||||
$(".preupload-room").click(function() {
|
||||
updatePreuploadPresentationModal(this)
|
||||
})
|
||||
|
||||
$("#remove-presentation").click(function(data) {
|
||||
removePreuploadPresentation($(this).data("remove"))
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
@ -138,11 +161,11 @@ function showCreateRoom(target) {
|
||||
$("#room_access_code").val(null)
|
||||
|
||||
$("#createRoomModal form").attr("action", $("body").data('relative-root'))
|
||||
|
||||
$("#room_mute_on_join").prop("checked", $("#room_mute_on_join").data("default"))
|
||||
$("#room_require_moderator_approval").prop("checked", $("#room_require_moderator_approval").data("default"))
|
||||
$("#room_anyone_can_start").prop("checked", $("#room_anyone_can_start").data("default"))
|
||||
$("#room_all_join_moderator").prop("checked", $("#room_all_join_moderator").data("default"))
|
||||
$("#room_recording").prop("checked", $("#room_recording").data("default"))
|
||||
|
||||
//show all elements & their children with a create-only class
|
||||
$(".create-only").each(function() {
|
||||
@ -197,12 +220,12 @@ function showDeleteRoom(target) {
|
||||
//Update the createRoomModal to show the correct current settings
|
||||
function updateCurrentSettings(settings_path){
|
||||
// Get current room settings and set checkbox
|
||||
$.get(settings_path, function(room_settings) {
|
||||
var settings = JSON.parse(room_settings)
|
||||
$.get(settings_path, function(settings) {
|
||||
$("#room_mute_on_join").prop("checked", $("#room_mute_on_join").data("default") || settings.muteOnStart)
|
||||
$("#room_require_moderator_approval").prop("checked", $("#room_require_moderator_approval").data("default") || settings.requireModeratorApproval)
|
||||
$("#room_anyone_can_start").prop("checked", $("#room_anyone_can_start").data("default") || settings.anyoneCanStart)
|
||||
$("#room_all_join_moderator").prop("checked", $("#room_all_join_moderator").data("default") || settings.joinModerator)
|
||||
$("#room_recording").prop("checked", $("#room_recording").data("default") || Boolean(settings.recording))
|
||||
})
|
||||
}
|
||||
|
||||
@ -264,3 +287,44 @@ function removeSharedUser(target) {
|
||||
parentLI.classList.add("remove-shared")
|
||||
}
|
||||
}
|
||||
|
||||
function updatePreuploadPresentationModal(target) {
|
||||
$.get($(target).data("settings-path"), function(presentation) {
|
||||
if(presentation.attached) {
|
||||
$("#current-presentation").show()
|
||||
$("#presentation-name").text(presentation.name)
|
||||
$("#change-pres").show()
|
||||
$("#use-pres").hide()
|
||||
} else {
|
||||
$("#current-presentation").hide()
|
||||
$("#change-pres").hide()
|
||||
$("#use-pres").show()
|
||||
}
|
||||
});
|
||||
|
||||
$("#preuploadPresentationModal form").attr("action", $(target).data("path"))
|
||||
$("#remove-presentation").data("remove", $(target).data("remove"))
|
||||
|
||||
// Reset values to original to prevent confusion
|
||||
$("#presentation-upload").val("")
|
||||
$("#presentation-upload-label").text($("#presentation-upload-label").data("placeholder"))
|
||||
$("#invalid-file-type").hide()
|
||||
}
|
||||
|
||||
function removePreuploadPresentation(path) {
|
||||
$.post(path, {})
|
||||
}
|
||||
|
||||
function validFileUpload(file) {
|
||||
return file.size/1024/1024 <= 30
|
||||
}
|
||||
|
||||
// Automatically click the join button if this is an action cable reload
|
||||
function checkIfAutoJoin() {
|
||||
var url = new URL(window.location.href)
|
||||
|
||||
if (url.searchParams.get("reload") == "true") {
|
||||
$("#joiner-consent").click()
|
||||
$("#room-join").click()
|
||||
}
|
||||
}
|
@ -27,6 +27,7 @@ $(document).on("turbolinks:load", function(){
|
||||
}, {
|
||||
connected: function() {
|
||||
console.log("connected");
|
||||
setTimeout(startRefreshTimeout, 120000);
|
||||
},
|
||||
|
||||
disconnected: function(data) {
|
||||
@ -40,7 +41,7 @@ $(document).on("turbolinks:load", function(){
|
||||
|
||||
received: function(data){
|
||||
console.log(data);
|
||||
if(data.action = "started"){
|
||||
if(data.action == "started"){
|
||||
request_to_join_meeting();
|
||||
}
|
||||
}
|
||||
@ -68,3 +69,10 @@ var request_to_join_meeting = function(){
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Refresh the page after 2 mins and attempt to reconnect to ActionCable
|
||||
function startRefreshTimeout() {
|
||||
var url = new URL(window.location.href)
|
||||
url.searchParams.set("reload","true")
|
||||
window.location.href = url.href
|
||||
}
|
||||
|
@ -84,10 +84,8 @@
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.manage-users-tab {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
#manage-users-nav.nav-tabs .nav-item {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
#merge-account-arrow {
|
||||
@ -96,4 +94,8 @@
|
||||
right: 47%;
|
||||
z-index: 999;
|
||||
background: white;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-tabs {
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
@ -145,6 +145,10 @@ input:focus {
|
||||
border-color: $primary !important;
|
||||
}
|
||||
|
||||
.input-group button:focus {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.list-group-item-action.active {
|
||||
color: $primary;
|
||||
}
|
||||
|
@ -113,3 +113,12 @@
|
||||
background: lightgray;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#recording-table .edit_hover_class {
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
#room-owner-name {
|
||||
line-height: 12px;
|
||||
}
|
@ -47,6 +47,7 @@ class AdminsController < ApplicationController
|
||||
|
||||
# GET /admins/site_settings
|
||||
def site_settings
|
||||
@tab = params[:tab] || "appearance"
|
||||
end
|
||||
|
||||
# GET /admins/server_recordings
|
||||
@ -191,6 +192,7 @@ class AdminsController < ApplicationController
|
||||
|
||||
# POST /admins/update_settings
|
||||
def update_settings
|
||||
tab = params[:tab] || "settings"
|
||||
@settings.update_value(params[:setting], params[:value])
|
||||
|
||||
flash_message = I18n.t("administrator.flash.settings")
|
||||
@ -199,7 +201,7 @@ class AdminsController < ApplicationController
|
||||
flash_message += ". " + I18n.t("administrator.site_settings.recording_visibility.warning")
|
||||
end
|
||||
|
||||
redirect_to admin_site_settings_path, flash: { success: flash_message }
|
||||
redirect_to admin_site_settings_path(tab: tab), flash: { success: flash_message }
|
||||
end
|
||||
|
||||
# POST /admins/color
|
||||
@ -207,7 +209,7 @@ class AdminsController < ApplicationController
|
||||
@settings.update_value("Primary Color", params[:value])
|
||||
@settings.update_value("Primary Color Lighten", color_lighten(params[:value]))
|
||||
@settings.update_value("Primary Color Darken", color_darken(params[:value]))
|
||||
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
|
||||
redirect_to admin_site_settings_path(tab: "appearance"), flash: { success: I18n.t("administrator.flash.settings") }
|
||||
end
|
||||
|
||||
# POST /admins/registration_method/:method
|
||||
@ -216,11 +218,11 @@ class AdminsController < ApplicationController
|
||||
|
||||
# Only allow change to Join by Invitation if user has emails enabled
|
||||
if !Rails.configuration.enable_email_verification && new_method == Rails.configuration.registration_methods[:invite]
|
||||
redirect_to admin_site_settings_path,
|
||||
redirect_to admin_site_settings_path(tab: "settings"),
|
||||
flash: { alert: I18n.t("administrator.flash.invite_email_verification") }
|
||||
else
|
||||
@settings.update_value("Registration Method", new_method)
|
||||
redirect_to admin_site_settings_path,
|
||||
redirect_to admin_site_settings_path(tab: "settings"),
|
||||
flash: { success: I18n.t("administrator.flash.registration_method_updated") }
|
||||
end
|
||||
end
|
||||
@ -229,7 +231,7 @@ class AdminsController < ApplicationController
|
||||
def clear_auth
|
||||
User.include_deleted.where(provider: @user_domain).update_all(social_uid: nil)
|
||||
|
||||
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
|
||||
redirect_to admin_site_settings_path(tab: "settings"), flash: { success: I18n.t("administrator.flash.settings") }
|
||||
end
|
||||
|
||||
# POST /admins/clear_cache
|
||||
@ -237,14 +239,14 @@ class AdminsController < ApplicationController
|
||||
Rails.cache.delete("#{@user_domain}/getUser")
|
||||
Rails.cache.delete("#{@user_domain}/getUserGreenlightCredentials")
|
||||
|
||||
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
|
||||
redirect_to admin_site_settings_path(tab: "settings"), flash: { success: I18n.t("administrator.flash.settings") }
|
||||
end
|
||||
|
||||
# POST /admins/log_level
|
||||
def log_level
|
||||
Rails.logger.level = params[:value].to_i
|
||||
|
||||
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
|
||||
redirect_to admin_site_settings_path(tab: "administration"), flash: { success: I18n.t("administrator.flash.settings") }
|
||||
end
|
||||
|
||||
# ROOM CONFIGURATION
|
||||
|
@ -84,9 +84,9 @@ class ApplicationController < ActionController::Base
|
||||
help: I18n.t("errors.maintenance.help"),
|
||||
}
|
||||
end
|
||||
if Rails.configuration.maintenance_window.present?
|
||||
unless cookies[:maintenance_window] == Rails.configuration.maintenance_window
|
||||
flash.now[:maintenance] = Rails.configuration.maintenance_window
|
||||
if @settings.get_value("Maintenance Banner").present?
|
||||
unless cookies[:maintenance_window] == @settings.get_value("Maintenance Banner")
|
||||
flash.now[:maintenance] = @settings.get_value("Maintenance Banner")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -182,6 +182,18 @@ class ApplicationController < ActionController::Base
|
||||
end
|
||||
helper_method :shared_access_allowed
|
||||
|
||||
# Indicates whether users are allowed to share rooms
|
||||
def recording_consent_required?
|
||||
@settings.get_value("Require Recording Consent") == "true"
|
||||
end
|
||||
helper_method :recording_consent_required?
|
||||
|
||||
# Returns a list of allowed file types
|
||||
def allowed_file_types
|
||||
Rails.configuration.allowed_file_types
|
||||
end
|
||||
helper_method :allowed_file_types
|
||||
|
||||
# Returns the page that the logo redirects to when clicked on
|
||||
def home_page
|
||||
return admins_path if current_user.has_role? :super_admin
|
||||
|
@ -61,7 +61,7 @@ module BbbServer
|
||||
# Creates a meeting on the BigBlueButton server.
|
||||
def start_session(room, options = {})
|
||||
create_options = {
|
||||
record: options[:meeting_recorded].to_s,
|
||||
record: options[:record].to_s,
|
||||
logoutURL: options[:meeting_logout_url] || '',
|
||||
moderatorPW: room.moderator_pw,
|
||||
attendeePW: room.attendee_pw,
|
||||
@ -77,11 +77,17 @@ module BbbServer
|
||||
|
||||
# Send the create request.
|
||||
begin
|
||||
meeting = bbb_server.create_meeting(room.name, room.bbb_id, create_options)
|
||||
# Update session info.
|
||||
meeting = if room.presentation.attached?
|
||||
modules = BigBlueButton::BigBlueButtonModules.new
|
||||
logger.info("Support: Room #{room.uid} starting using presentation: #{rails_blob_url(room.presentation)}")
|
||||
modules.add_presentation(:url, rails_blob_url(room.presentation))
|
||||
bbb_server.create_meeting(room.name, room.bbb_id, create_options, modules)
|
||||
else
|
||||
bbb_server.create_meeting(room.name, room.bbb_id, create_options)
|
||||
end
|
||||
|
||||
unless meeting[:messageKey] == 'duplicateWarning'
|
||||
room.update_attributes(sessions: room.sessions + 1,
|
||||
last_session: DateTime.now)
|
||||
room.update_attributes(sessions: room.sessions + 1, last_session: DateTime.now)
|
||||
end
|
||||
rescue BigBlueButton::BigBlueButtonException => e
|
||||
puts "BigBlueButton failed on create: #{e.key}: #{e.message}"
|
||||
|
@ -105,6 +105,8 @@ module Joiner
|
||||
"Room Configuration All Join Moderator"
|
||||
when "anyoneCanStart"
|
||||
"Room Configuration Allow Any Start"
|
||||
when "recording"
|
||||
"Room Configuration Recording"
|
||||
end
|
||||
|
||||
case @settings.get_value(config)
|
||||
|
@ -27,7 +27,7 @@ class RoomsController < ApplicationController
|
||||
unless: -> { !Rails.configuration.enable_email_verification }
|
||||
before_action :find_room, except: [:create, :join_specific_room, :cant_create_rooms]
|
||||
before_action :verify_room_ownership_or_admin_or_shared, only: [:start, :shared_access]
|
||||
before_action :verify_room_ownership_or_admin, only: [:update_settings, :destroy]
|
||||
before_action :verify_room_ownership_or_admin, only: [:update_settings, :destroy, :preupload_presentation, :remove_presentation]
|
||||
before_action :verify_room_ownership_or_shared, only: [:remove_shared_access]
|
||||
before_action :verify_room_owner_verified, only: [:show, :join],
|
||||
unless: -> { !Rails.configuration.enable_email_verification }
|
||||
@ -171,6 +171,7 @@ class RoomsController < ApplicationController
|
||||
@room_settings = JSON.parse(@room[:room_settings])
|
||||
opts[:mute_on_start] = room_setting_with_config("muteOnStart")
|
||||
opts[:require_moderator_approval] = room_setting_with_config("requireModeratorApproval")
|
||||
opts[:record] = record_meeting
|
||||
|
||||
begin
|
||||
redirect_to join_path(@room, current_user.name, opts, current_user.uid)
|
||||
@ -209,6 +210,45 @@ class RoomsController < ApplicationController
|
||||
redirect_back fallback_location: room_path(@room)
|
||||
end
|
||||
|
||||
# GET /:room_uid/current_presentation
|
||||
def current_presentation
|
||||
attached = @room.presentation.attached?
|
||||
|
||||
# Respond with JSON object of presentation name
|
||||
respond_to do |format|
|
||||
format.json { render body: { attached: attached, name: attached ? @room.presentation.filename.to_s : "" }.to_json }
|
||||
end
|
||||
end
|
||||
|
||||
# POST /:room_uid/preupload_presenstation
|
||||
def preupload_presentation
|
||||
begin
|
||||
raise "Invalid file type" unless valid_file_type
|
||||
@room.presentation.attach(room_params[:presentation])
|
||||
|
||||
flash[:success] = I18n.t("room.preupload_success")
|
||||
rescue => e
|
||||
logger.error "Support: Error in updating room presentation: #{e}"
|
||||
flash[:alert] = I18n.t("room.preupload_error")
|
||||
end
|
||||
|
||||
redirect_back fallback_location: room_path(@room)
|
||||
end
|
||||
|
||||
# POST /:room_uid/remove_presenstation
|
||||
def remove_presentation
|
||||
begin
|
||||
@room.presentation.purge
|
||||
|
||||
flash[:success] = I18n.t("room.preupload_remove_success")
|
||||
rescue => e
|
||||
logger.error "Support: Error in removing room presentation: #{e}"
|
||||
flash[:alert] = I18n.t("room.preupload_remove_error")
|
||||
end
|
||||
|
||||
redirect_back fallback_location: room_path(@room)
|
||||
end
|
||||
|
||||
# POST /:room_uid/update_shared_access
|
||||
def shared_access
|
||||
begin
|
||||
@ -240,7 +280,7 @@ class RoomsController < ApplicationController
|
||||
# POST /:room_uid/remove_shared_access
|
||||
def remove_shared_access
|
||||
begin
|
||||
SharedAccess.find_by!(room_id: @room.id, user_id: params[:user_id]).destroy
|
||||
SharedAccess.find_by!(room_id: @room.id, user_id: current_user).destroy
|
||||
flash[:success] = I18n.t("room.remove_shared_access_success")
|
||||
rescue => e
|
||||
logger.error "Support: Error in removing room shared access: #{e}"
|
||||
@ -262,7 +302,7 @@ class RoomsController < ApplicationController
|
||||
def room_settings
|
||||
# Respond with JSON object of the room_settings
|
||||
respond_to do |format|
|
||||
format.json { render body: @room.room_settings.to_json }
|
||||
format.json { render body: @room.room_settings }
|
||||
end
|
||||
end
|
||||
|
||||
@ -291,6 +331,7 @@ class RoomsController < ApplicationController
|
||||
"requireModeratorApproval": options[:require_moderator_approval] == "1",
|
||||
"anyoneCanStart": options[:anyone_can_start] == "1",
|
||||
"joinModerator": options[:all_join_moderator] == "1",
|
||||
"recording": options[:recording] == "1",
|
||||
}
|
||||
|
||||
room_settings.to_json
|
||||
@ -298,7 +339,8 @@ class RoomsController < ApplicationController
|
||||
|
||||
def room_params
|
||||
params.require(:room).permit(:name, :auto_join, :mute_on_join, :access_code,
|
||||
:require_moderator_approval, :anyone_can_start, :all_join_moderator)
|
||||
:require_moderator_approval, :anyone_can_start, :all_join_moderator,
|
||||
:recording, :presentation)
|
||||
end
|
||||
|
||||
# Find the room from the uid.
|
||||
@ -364,4 +406,18 @@ class RoomsController < ApplicationController
|
||||
current_user.rooms.length >= limit
|
||||
end
|
||||
helper_method :room_limit_exceeded
|
||||
|
||||
def record_meeting
|
||||
# If the require consent setting is checked, then check the room setting, else, set to true
|
||||
if recording_consent_required?
|
||||
room_setting_with_config("recording")
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
# Checks if the file extension is allowed
|
||||
def valid_file_type
|
||||
Rails.configuration.allowed_file_types.split(",").include?(File.extname(room_params[:presentation].original_filename))
|
||||
end
|
||||
end
|
||||
|
@ -61,6 +61,14 @@ module AdminsHelper
|
||||
end
|
||||
end
|
||||
|
||||
def preupload_string
|
||||
if @settings.get_value("Preupload Presentation") == "true"
|
||||
I18n.t("administrator.site_settings.authentication.enabled")
|
||||
else
|
||||
I18n.t("administrator.site_settings.authentication.disabled")
|
||||
end
|
||||
end
|
||||
|
||||
def recording_default_visibility_string
|
||||
if @settings.get_value("Default Recording Visibility") == "public"
|
||||
I18n.t("recording.visibility.public")
|
||||
@ -80,6 +88,14 @@ module AdminsHelper
|
||||
end
|
||||
end
|
||||
|
||||
def require_consent_string
|
||||
if @settings.get_value("Require Recording Consent") == "true"
|
||||
I18n.t("administrator.site_settings.authentication.enabled")
|
||||
else
|
||||
I18n.t("administrator.site_settings.authentication.disabled")
|
||||
end
|
||||
end
|
||||
|
||||
def log_level_string
|
||||
case Rails.logger.level
|
||||
when 0
|
||||
@ -97,6 +113,10 @@ module AdminsHelper
|
||||
end
|
||||
end
|
||||
|
||||
def show_log_dropdown
|
||||
current_user.has_role?(:super_admin) || !Rails.configuration.loadbalanced_configuration
|
||||
end
|
||||
|
||||
def room_limit_number
|
||||
@settings.get_value("Room Limit").to_i
|
||||
end
|
||||
|
@ -117,4 +117,11 @@ module ApplicationHelper
|
||||
rescue
|
||||
false
|
||||
end
|
||||
|
||||
# Specifies which title should be the tab title and returns original string
|
||||
def title(page_title)
|
||||
# Only set the content_for if not already set on the page so that only the first title appears as the tab title
|
||||
content_for(:page_title) { page_title } if content_for(:page_title).blank?
|
||||
page_title
|
||||
end
|
||||
end
|
||||
|
@ -41,4 +41,8 @@ module RoomsHelper
|
||||
def room_configuration(name)
|
||||
@settings.get_value(name)
|
||||
end
|
||||
|
||||
def preupload_allowed?
|
||||
@settings.get_value("Preupload Presentation") == "true"
|
||||
end
|
||||
end
|
||||
|
@ -36,4 +36,8 @@ module ThemingHelper
|
||||
def user_color
|
||||
@settings.get_value("Primary Color") || Rails.configuration.primary_color_default
|
||||
end
|
||||
|
||||
def maintenance_banner
|
||||
@settings.get_value("Maintenance Banner")
|
||||
end
|
||||
end
|
||||
|
@ -28,7 +28,7 @@ class Ability
|
||||
highest_role = user.role
|
||||
if highest_role.get_permission("can_edit_site_settings")
|
||||
can [:site_settings, :room_configuration, :update_settings,
|
||||
:update_room_configuration, :coloring, :registration_method], :admin
|
||||
:update_room_configuration, :coloring, :registration_method, :log_level], :admin
|
||||
end
|
||||
|
||||
if highest_role.get_permission("can_edit_roles")
|
||||
|
@ -23,11 +23,15 @@ class Room < ApplicationRecord
|
||||
|
||||
before_create :setup
|
||||
|
||||
before_destroy :destroy_presentation
|
||||
|
||||
validates :name, presence: true
|
||||
|
||||
belongs_to :owner, class_name: 'User', foreign_key: :user_id
|
||||
has_many :shared_access
|
||||
|
||||
has_one_attached :presentation
|
||||
|
||||
def self.admins_search(string)
|
||||
active_database = Rails.configuration.database_configuration[Rails.env]["adapter"]
|
||||
# Postgres requires created_at to be cast to a string
|
||||
@ -51,6 +55,8 @@ class Room < ApplicationRecord
|
||||
# Rely on manual ordering if trying to sort by status
|
||||
return order_by_status(table, running_ids) if column == "status"
|
||||
|
||||
return table.order("COALESCE(rooms.last_session,rooms.created_at) DESC") if column == "created_at"
|
||||
|
||||
return table.order(Arel.sql("rooms.#{column} #{direction}")) if table.column_names.include?(column)
|
||||
|
||||
return table.order(Arel.sql("#{column} #{direction}")) if column == "users.name"
|
||||
@ -86,15 +92,17 @@ class Room < ApplicationRecord
|
||||
def self.order_by_status(table, ids)
|
||||
return table if ids.blank?
|
||||
|
||||
order_string = "CASE bbb_id "
|
||||
# Get active rooms first
|
||||
active_rooms = table.where(bbb_id: ids)
|
||||
|
||||
ids.each_with_index do |id, index|
|
||||
order_string += "WHEN '#{id}' THEN #{index} "
|
||||
end
|
||||
# Get other rooms sorted by last session date || created at date (whichever is higher)
|
||||
inactive_rooms = table.where.not(bbb_id: ids).order("COALESCE(rooms.last_session,rooms.created_at) DESC")
|
||||
|
||||
order_string += "ELSE #{ids.length} END"
|
||||
active_rooms + inactive_rooms
|
||||
end
|
||||
|
||||
table.order(Arel.sql(order_string))
|
||||
def recording_enabled?
|
||||
JSON.parse(room_settings)["recording"]
|
||||
end
|
||||
|
||||
private
|
||||
@ -110,9 +118,9 @@ class Room < ApplicationRecord
|
||||
# Generates a fully random room uid.
|
||||
def random_room_uid
|
||||
# 6 character long random string of chars from a..z and 0..9
|
||||
full_chunk = SecureRandom.alphanumeric(6).downcase
|
||||
full_chunk = SecureRandom.alphanumeric(9).downcase
|
||||
|
||||
[owner.name_chunk, full_chunk[0..2], full_chunk[3..5]].join("-")
|
||||
[owner.name_chunk, full_chunk[0..2], full_chunk[3..5], full_chunk[6..8]].join("-")
|
||||
end
|
||||
|
||||
# Generates a unique bbb_id based on uuid.
|
||||
@ -122,4 +130,9 @@ class Room < ApplicationRecord
|
||||
break bbb_id unless Room.exists?(bbb_id: bbb_id)
|
||||
end
|
||||
end
|
||||
|
||||
# Before destroying the room, make sure you also destroy the presentation attached
|
||||
def destroy_presentation
|
||||
presentation.purge if presentation.attached?
|
||||
end
|
||||
end
|
||||
|
@ -58,10 +58,14 @@ class Setting < ApplicationRecord
|
||||
Rails.configuration.registration_method_default
|
||||
when "Room Authentication"
|
||||
false
|
||||
when "Require Recording Consent"
|
||||
Rails.configuration.require_consent_default
|
||||
when "Room Limit"
|
||||
Rails.configuration.number_of_rooms_default
|
||||
when "Shared Access"
|
||||
Rails.configuration.shared_access_default
|
||||
when "Preupload Presentation"
|
||||
Rails.configuration.preupload_presentation_default
|
||||
when "Room Configuration Mute On Join"
|
||||
room_config_setting("mute-on-join")
|
||||
when "Room Configuration Require Moderator"
|
||||
@ -70,6 +74,8 @@ class Setting < ApplicationRecord
|
||||
room_config_setting("anyone-can-start")
|
||||
when "Room Configuration All Join Moderator"
|
||||
room_config_setting("all-join-moderator")
|
||||
when "Room Configuration Recording"
|
||||
room_config_setting("recording")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -13,6 +13,6 @@
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
%>
|
||||
|
||||
<button style="<%= "background-color: #{role_colour(role)};border-color: #{role_colour(role)}" %>" class="user-role btn btn-sm" onclick="filterRole('<%= role.name %>')">
|
||||
<button style="<%= "background-color: #{role_colour(role)};border-color: #{role_colour(role)}" %>" class="user-role btn btn-sm" onclick="filterRole('<%= escape_javascript(role.name) %>')">
|
||||
<%= translated_role_name(role) %>
|
||||
</button>
|
@ -1,5 +1,5 @@
|
||||
<%
|
||||
# BigBlueButton open source conferencing system - http://www.bigbluespan.org/.
|
||||
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
|
||||
# This program is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||
@ -14,20 +14,25 @@
|
||||
%>
|
||||
|
||||
<div class="form-group mt-n3">
|
||||
<div class="row">
|
||||
<div class="col-12 tags">
|
||||
<span id="active" class="btn btn-sm tag manage-users-tab <%= 'selected' if @tab == 'active' %>">
|
||||
<nav class="row m-0">
|
||||
<div class="nav col nav-tabs admin-tabs m-0 p-0" id="manage-users-nav" role="tablist">
|
||||
<a class="nav-item p-3 nav-link <%= 'active' if @tab == 'active' %>" id="Active" href="?tab=active" role="tab" aria-selected="true"><i class="fas mr-3 fa-users"></i>
|
||||
<%= t("roles.active") %>
|
||||
</span>
|
||||
<span id="pending" class="btn btn-sm tag manage-users-tab <%= 'selected' if @tab == 'pending' %>">
|
||||
</a>
|
||||
<a class="nav-item p-3 nav-link <%= 'active' if @tab == 'pending' %>" id="Pending" href="?tab=pending" role="tab" aria-selected="false"><i class="fas mr-3 fa-user-clock"></i>
|
||||
<%= t("roles.pending") %>
|
||||
</span>
|
||||
<span id="denied" class="btn btn-sm tag manage-users-tab <%= 'selected' if @tab == 'denied' %>">
|
||||
</a>
|
||||
<a class="nav-item p-3 nav-link <%= 'active' if @tab == 'denied' %>" id="Denied" href="?tab=denied" role="tab" aria-selected="false"><i class="fas mr-3 fa-user-times"></i>
|
||||
<%= t("roles.banned") %>
|
||||
</span>
|
||||
<span id="deleted" class="btn btn-sm tag manage-users-tab <%= 'selected' if @tab == 'deleted' %>">
|
||||
</a>
|
||||
<a class="nav-item p-3 nav-link <%= 'active' if @tab == 'deleted' %>" id="Deleted" href="?tab=deleted" role="tab" aria-selected="false"><i class="far mr-2 fa-trash-alt"></i>
|
||||
<%= t("roles.deleted") %>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% if admin_invite_registration %>
|
||||
<%= link_to "#inviteModal", class: "btn btn-primary pt-3", id: "invite-user", "data-toggle": "modal" do %>
|
||||
<%= t("administrator.users.invite") %><i class="fas fa-paper-plane ml-3"></i>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</nav>
|
||||
</div>
|
||||
|
@ -98,4 +98,31 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% if recording_consent_required? %>
|
||||
<div class="mb-6 row">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("modal.room_settings.recording") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.room_configuration.recordings.info") %></label>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<%= room_configuration_string("Room Configuration Recording") %>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<%= button_to admin_update_room_configuration_path(setting: "Room Configuration Recording", value: "enabled"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.room_configuration.options.enabled") %>
|
||||
<% end %>
|
||||
<%= button_to admin_update_room_configuration_path(setting: "Room Configuration Recording", value: "optional"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.room_configuration.options.optional") %>
|
||||
<% end %>
|
||||
<%= button_to admin_update_room_configuration_path(setting: "Room Configuration Recording", value: "disabled"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.room_configuration.options.disabled") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
|
@ -65,6 +65,11 @@
|
||||
<a href="" data-toggle="modal" data-target="#createRoomModal" class="update-room dropdown-item" data-settings-path="<%= room_settings_path(room) %>">
|
||||
<i class="dropdown-icon fas fa-cog"></i> <%= t("room.settings") %>
|
||||
</a>
|
||||
<% if preupload_allowed? %>
|
||||
<a href="" data-toggle="modal" data-target="#preuploadPresentationModal" class="preupload-room dropdown-item" data-path="<%= preupload_presentation_path(room) %>" data-settings-path="<%= current_presentation_path(room) %>" data-remove="<%= remove_presentation_path(room) %>">
|
||||
<i class="dropdown-icon fas fa-file-upload"></i> <%= t("room.add_presentation") %>
|
||||
</a>
|
||||
<% end %>
|
||||
<% if shared_access_allowed %>
|
||||
<a href="" data-toggle="modal" data-target="#shareRoomModal" class="share-room dropdown-item" data-path="<%= room_shared_access_path(room) %>" data-users-path="<%= room_shared_users_path(room) %>">
|
||||
<i class="dropdown-icon fas fa-users"></i> <%= t("room.share") %>
|
||||
|
@ -13,247 +13,30 @@
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
%>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="mb-6 form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.branding.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.branding.info") %></label>
|
||||
<div class="input-group">
|
||||
<input id="branding-url" type="text" class="form-control" value="<%= logo_image %>">
|
||||
<span class="input-group-append">
|
||||
<button id="branding-image" onclick="changeBrandingImage('<%= admin_update_settings_path(setting: 'Branding Image') %>')" class="btn btn-primary" type="button"><%= t("administrator.site_settings.branding.change") %></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group mt-n3">
|
||||
<nav class="row m-0">
|
||||
<div class="nav col nav-tabs admin-tabs m-0 p-0" >
|
||||
<a class="nav-item p-3 nav-link <%= 'active' if @tab == 'appearance' %>" href="?tab=appearance" role="tab" aria-selected="true">
|
||||
<i class="fas mr-3 fa-palette"></i>
|
||||
<%= t("administrator.site_settings.tabs.appearance") %>
|
||||
</a>
|
||||
<a class="nav-item p-3 nav-link <%= 'active' if @tab == 'administration' %>" href="?tab=administration" role="tab" aria-selected="false">
|
||||
<i class="fas mr-3 fa-toolbox"></i>
|
||||
<%= t("administrator.site_settings.tabs.administration") %>
|
||||
</a>
|
||||
<a class="nav-item p-3 nav-link <%= 'active' if @tab == 'settings' %>" href="?tab=settings" role="tab" aria-selected="false">
|
||||
<i class="fas mr-3 fa-tools"></i>
|
||||
<%= t("administrator.site_settings.tabs.settings") %>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="mb-6 form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.legal.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.legal.info") %></label>
|
||||
<div class="input-group">
|
||||
<input id="legal-url" type="text" class="form-control" value="<%= legal_url %>">
|
||||
<span class="input-group-append">
|
||||
<button id="legal-url" onclick="changeLegalURL('<%= admin_update_settings_path(setting: 'Legal URL') %>')" class="btn btn-primary" type="button"><%= t("administrator.site_settings.legal.change") %></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="mb-6 form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.privpolicy.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.privpolicy.info") %></label>
|
||||
<div class="input-group">
|
||||
<input id="privpolicy-url" type="text" class="form-control" value="<%= privpolicy_url %>">
|
||||
<span class="input-group-append">
|
||||
<button id="privpolicy-url" onclick="changePrivacyPolicyURL('<%= admin_update_settings_path(setting: 'Privacy Policy URL') %>')" class="btn btn-primary" type="button"><%= t("administrator.site_settings.privpolicy.change") %></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="mb-6 form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.color.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.color.info") %></label>
|
||||
<div class="color-inputs">
|
||||
<input id="coloring-path-regular" type="hidden" value="<%= admin_coloring_path %>">
|
||||
<input id="coloring-path-lighten" type="hidden" value="<%= admin_update_settings_path(setting: "Primary Color Lighten") %>">
|
||||
<input id="coloring-path-darken" type="hidden" value="<%= admin_update_settings_path(setting: "Primary Color Darken") %>">
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div id="colorinput-regular" class="btn primary-regular mr-3">
|
||||
<%= t("administrator.site_settings.color.regular") %>
|
||||
</div>
|
||||
|
||||
<div id="colorinput-lighten" class="btn primary-lighten mr-3">
|
||||
<%= t("administrator.site_settings.color.lighten") %>
|
||||
</div>
|
||||
|
||||
<div id="colorinput-darken" class="btn primary-darken">
|
||||
<%= t("administrator.site_settings.color.darken") %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="mb-6 col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.registration.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.registration.info") %></label>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" id="registrationMethods" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<%= registration_method_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="registrationMethods">
|
||||
<%= button_to admin_change_registration_path(value: "open"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.registration.methods.open") %>
|
||||
<% end %>
|
||||
<%= button_to admin_change_registration_path(value: "invite"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.registration.methods.invite") %>
|
||||
<% end %>
|
||||
<%= button_to admin_change_registration_path(value: "approval"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.registration.methods.approval") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-6 row">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.authentication.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.authentication.info") %></label>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" id="room-auth" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<%= room_authentication_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="room-auth">
|
||||
<%= button_to admin_update_settings_path(setting: "Room Authentication", value: "true"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.authentication.enabled") %>
|
||||
<% end %>
|
||||
<%= button_to admin_update_settings_path(setting: "Room Authentication", value: "false"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.authentication.disabled") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-6 row">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.shared_access.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.shared_access.info") %></label>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" id="room-auth" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<%= shared_access_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="room-auth">
|
||||
<%= button_to admin_update_settings_path(setting: "Shared Access", value: "true"), class: "dropdown-item" do %>
|
||||
<%= t("administrator.site_settings.authentication.enabled") %>
|
||||
<% end %>
|
||||
<%= button_to admin_update_settings_path(setting: "Shared Access", value: "false"), class: "dropdown-item" do %>
|
||||
<%= t("administrator.site_settings.authentication.disabled") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-6 row">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.recording_visibility.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.recording_visibility.info") %></label>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" id="room-auth" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<%= recording_default_visibility_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="room-auth">
|
||||
<%= button_to admin_update_settings_path(setting: "Default Recording Visibility", value: "public"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("recording.visibility.public") %>
|
||||
<% end %>
|
||||
<%= button_to admin_update_settings_path(setting: "Default Recording Visibility", value: "private"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("recording.visibility.unlisted") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-6 row">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.rooms.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.rooms.info") %></label>
|
||||
<div class="row gutters-xs">
|
||||
<div class="col-auto">
|
||||
<label class="colorinput">
|
||||
<%= button_to admin_update_settings_path(setting: "Room Limit", value: 1), class: "colorinput-input", "data-disable": "" do %><% end %>
|
||||
<span class="colorinput-color <%= room_limit_number == 1 ? "btn-primary" : "btn-outline-primary" %>">1</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label class="colorinput">
|
||||
<%= button_to admin_update_settings_path(setting: "Room Limit", value: 5), class: "colorinput-input", "data-disable": "" do %><% end %>
|
||||
<span class="colorinput-color <%= room_limit_number == 5 ? "btn-primary" : "btn-outline-primary" %>">5</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label class="colorinput">
|
||||
<%= button_to admin_update_settings_path(setting: "Room Limit", value: 10), class: "colorinput-input", "data-disable": "" do %><% end %>
|
||||
<span class="colorinput-color <%= room_limit_number == 10 ? "btn-primary" : "btn-outline-primary" %>">10</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label class="colorinput">
|
||||
<%= button_to admin_update_settings_path(setting: "Room Limit", value: 15), class: "colorinput-input", "data-disable": "" do %><% end %>
|
||||
<span class="colorinput-color <%= room_limit_number == 15 ? "btn-primary" : "btn-outline-primary" %>">15+</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% if current_user.has_role? :super_admin%>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="mb-6 form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.cache.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.cache.info") %></label>
|
||||
<%= button_to t("administrator.site_settings.cache.button"), admin_clear_cache_path, class: "btn btn-primary", "data-disable": "" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4 row">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.clear_auth.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.clear_auth.info") %></label>
|
||||
<%= button_to t("administrator.site_settings.clear_auth.button"), admin_clear_auth_path, class: "btn btn-primary" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4 row">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.log_level.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.log_level.information") %></label>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" id="room-auth" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<%= log_level_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="room-auth">
|
||||
<%= button_to admin_log_level_path(value: 0), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.debug") %>
|
||||
<% end %>
|
||||
<%= button_to admin_log_level_path(value: 1), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.info") %>
|
||||
<% end %>
|
||||
<%= button_to admin_log_level_path(value: 2), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.warn") %>
|
||||
<% end %>
|
||||
<%= button_to admin_log_level_path(value: 3), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.error") %>
|
||||
<% end %>
|
||||
<%= button_to admin_log_level_path(value: 4), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.fatal") %>
|
||||
<% end %>
|
||||
<%= button_to admin_log_level_path(value: 5), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.unknown") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @tab == "appearance"%>
|
||||
<%= render "admins/components/site_settings/appearance" %>
|
||||
<% elsif @tab == "administration"%>
|
||||
<%= render "admins/components/site_settings/administration" %>
|
||||
<% else %>
|
||||
<%= render "admins/components/site_settings/settings" %>
|
||||
<% end %>
|
||||
|
||||
|
@ -0,0 +1,96 @@
|
||||
<%
|
||||
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
|
||||
# This program is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
# You should have received a copy of the GNU Lesser General Public License along
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
%>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="row mb-2">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.maintenance_banner.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.maintenance_banner.info") %></label>
|
||||
<div class="input-group">
|
||||
<input id="maintenance-banner" type="text" class="form-control" value="<%= maintenance_banner %>" placeholder="<%= t("administrator.site_settings.maintenance_banner.time") %>">
|
||||
<span class="input-group-append">
|
||||
<button onclick="displayMaintenanceBanner('<%= admin_update_settings_path(setting: 'Maintenance Banner') %>')" class="settings-button btn btn-primary" type="button"><%= t("administrator.site_settings.maintenance_banner.display") %></button>
|
||||
<button onclick="clearMaintenanceBanner('<%= admin_update_settings_path(setting: 'Maintenance Banner') %>')" class="settings-button btn btn-danger" type="button"><%= t("administrator.site_settings.maintenance_banner.clear") %></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.legal.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.legal.info") %></label>
|
||||
<div class="input-group">
|
||||
<input id="legal-url" type="text" class="form-control" value="<%= legal_url %>">
|
||||
<span class="input-group-append">
|
||||
<button id="legal-url" onclick="changeLegalURL('<%= admin_update_settings_path(setting: 'Legal URL') %>')" class="btn btn-primary" type="button"><%= t("administrator.site_settings.legal.change") %></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.privpolicy.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.privpolicy.info") %></label>
|
||||
<div class="input-group">
|
||||
<input id="privpolicy-url" type="text" class="form-control" value="<%= privpolicy_url %>">
|
||||
<span class="input-group-append">
|
||||
<button id="privpolicy-url" onclick="changePrivacyPolicyURL('<%= admin_update_settings_path(setting: 'Privacy Policy URL') %>')" class="btn btn-primary" type="button"><%= t("administrator.site_settings.privpolicy.change") %></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% if show_log_dropdown %>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.log_level.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.log_level.information") %></label>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" id="room-auth" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<%= log_level_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="room-auth">
|
||||
<%= button_to admin_log_level_path(value: 0), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.debug") %>
|
||||
<% end %>
|
||||
<%= button_to admin_log_level_path(value: 1), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.info") %>
|
||||
<% end %>
|
||||
<%= button_to admin_log_level_path(value: 2), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.warn") %>
|
||||
<% end %>
|
||||
<%= button_to admin_log_level_path(value: 3), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.error") %>
|
||||
<% end %>
|
||||
<%= button_to admin_log_level_path(value: 4), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.fatal") %>
|
||||
<% end %>
|
||||
<%= button_to admin_log_level_path(value: 5), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.log_level.unknown") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
@ -0,0 +1,56 @@
|
||||
<%
|
||||
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
|
||||
# This program is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
# You should have received a copy of the GNU Lesser General Public License along
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
%>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="row mb-2">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.branding.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.branding.info") %></label>
|
||||
<div class="input-group">
|
||||
<input id="branding-url" type="text" class="form-control" value="<%= logo_image %>">
|
||||
<span class="input-group-append">
|
||||
<button id="branding-image" onclick="changeBrandingImage('<%= admin_update_settings_path(setting: 'Branding Image') %>')" class="btn btn-primary" type="button"><%= t("administrator.site_settings.branding.change") %></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.color.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.color.info") %></label>
|
||||
<div class="color-inputs">
|
||||
<input id="coloring-path-regular" type="hidden" value="<%= admin_coloring_path %>">
|
||||
<input id="coloring-path-lighten" type="hidden" value="<%= admin_update_settings_path(setting: "Primary Color Lighten") %>">
|
||||
<input id="coloring-path-darken" type="hidden" value="<%= admin_update_settings_path(setting: "Primary Color Darken") %>">
|
||||
|
||||
<div id="colorinput-regular" class="btn primary-regular mr-3">
|
||||
<%= t("administrator.site_settings.color.regular") %>
|
||||
</div>
|
||||
|
||||
<div id="colorinput-lighten" class="btn primary-lighten mr-3">
|
||||
<%= t("administrator.site_settings.color.lighten") %>
|
||||
</div>
|
||||
|
||||
<div id="colorinput-darken" class="btn primary-darken">
|
||||
<%= t("administrator.site_settings.color.darken") %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
201
app/views/admins/components/site_settings/_settings.html.erb
Normal file
201
app/views/admins/components/site_settings/_settings.html.erb
Normal file
@ -0,0 +1,201 @@
|
||||
<%
|
||||
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
|
||||
# This program is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
# You should have received a copy of the GNU Lesser General Public License along
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
%>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="row mb-2">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.registration.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.registration.info") %></label>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" id="registrationMethods" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<%= registration_method_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="registrationMethods">
|
||||
<%= button_to admin_change_registration_path(value: "open"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.registration.methods.open") %>
|
||||
<% end %>
|
||||
<%= button_to admin_change_registration_path(value: "invite"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.registration.methods.invite") %>
|
||||
<% end %>
|
||||
<%= button_to admin_change_registration_path(value: "approval"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.registration.methods.approval") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.authentication.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.authentication.info") %></label>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" id="room-auth" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<%= room_authentication_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="room-auth">
|
||||
<%= button_to admin_update_settings_path(setting: "Room Authentication", value: "true"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.authentication.enabled") %>
|
||||
<% end %>
|
||||
<%= button_to admin_update_settings_path(setting: "Room Authentication", value: "false"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.authentication.disabled") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.shared_access.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.shared_access.info") %></label>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" id="room-auth" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<%= shared_access_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="room-auth">
|
||||
<%= button_to admin_update_settings_path(setting: "Shared Access", value: "true"), class: "dropdown-item" do %>
|
||||
<%= t("administrator.site_settings.authentication.enabled") %>
|
||||
<% end %>
|
||||
<%= button_to admin_update_settings_path(setting: "Shared Access", value: "false"), class: "dropdown-item" do %>
|
||||
<%= t("administrator.site_settings.authentication.disabled") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.preupload.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.preupload.info") %></label>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" id="room-auth" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<%= preupload_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="room-auth">
|
||||
<%= button_to admin_update_settings_path(setting: "Preupload Presentation", value: "true"), class: "dropdown-item" do %>
|
||||
<%= t("administrator.site_settings.authentication.enabled") %>
|
||||
<% end %>
|
||||
<%= button_to admin_update_settings_path(setting: "Preupload Presentation", value: "false"), class: "dropdown-item" do %>
|
||||
<%= t("administrator.site_settings.authentication.disabled") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.recording_visibility.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.recording_visibility.info") %></label>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" id="room-auth" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<%= recording_default_visibility_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="room-auth">
|
||||
<%= button_to admin_update_settings_path(setting: "Default Recording Visibility", value: "public"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("recording.visibility.public") %>
|
||||
<% end %>
|
||||
<%= button_to admin_update_settings_path(setting: "Default Recording Visibility", value: "private"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("recording.visibility.unlisted") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.require_consent.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.require_consent.info") %></label>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<%= require_consent_string %>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="room-auth">
|
||||
<%= button_to admin_update_settings_path(setting: "Require Recording Consent", value: "true"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.authentication.enabled") %>
|
||||
<% end %>
|
||||
<%= button_to admin_update_settings_path(setting: "Require Recording Consent", value: "false"), class: "dropdown-item", "data-disable": "" do %>
|
||||
<%= t("administrator.site_settings.authentication.disabled") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.rooms.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.rooms.info") %></label>
|
||||
<div class="row gutters-xs">
|
||||
<div class="col-auto">
|
||||
<label class="colorinput">
|
||||
<%= button_to admin_update_settings_path(setting: "Room Limit", value: 1), class: "colorinput-input", "data-disable": "" do %><% end %>
|
||||
<span class="colorinput-color <%= room_limit_number == 1 ? "btn-primary" : "btn-outline-primary" %>">1</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label class="colorinput">
|
||||
<%= button_to admin_update_settings_path(setting: "Room Limit", value: 5), class: "colorinput-input", "data-disable": "" do %><% end %>
|
||||
<span class="colorinput-color <%= room_limit_number == 5 ? "btn-primary" : "btn-outline-primary" %>">5</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label class="colorinput">
|
||||
<%= button_to admin_update_settings_path(setting: "Room Limit", value: 10), class: "colorinput-input", "data-disable": "" do %><% end %>
|
||||
<span class="colorinput-color <%= room_limit_number == 10 ? "btn-primary" : "btn-outline-primary" %>">10</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label class="colorinput">
|
||||
<%= button_to admin_update_settings_path(setting: "Room Limit", value: 15), class: "colorinput-input", "data-disable": "" do %><% end %>
|
||||
<span class="colorinput-color <%= room_limit_number == 15 ? "btn-primary" : "btn-outline-primary" %>">15+</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% if current_user.has_role? :super_admin %>
|
||||
<hr>
|
||||
<div class="row mb-2">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.cache.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.cache.info") %></label>
|
||||
<%= button_to t("administrator.site_settings.cache.button"), admin_clear_cache_path, class: "btn btn-primary", "data-disable": "" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%= t("administrator.site_settings.clear_auth.title") %></label>
|
||||
<label class="form-label text-muted"><%= t("administrator.site_settings.clear_auth.info") %></label>
|
||||
<%= button_to t("administrator.site_settings.clear_auth.button"), admin_clear_auth_path, class: "btn btn-primary" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
@ -28,6 +28,9 @@
|
||||
|
||||
<%= render "shared/modals/delete_room_modal" %>
|
||||
<%= render "shared/modals/create_room_modal" %>
|
||||
<% if preupload_allowed? %>
|
||||
<%= render "shared/modals/preupload_presentation_modal" %>
|
||||
<% end %>
|
||||
<% if shared_access_allowed %>
|
||||
<%= render "shared/modals/share_room_modal" %>
|
||||
<% end %>
|
@ -28,13 +28,12 @@
|
||||
</script>
|
||||
<% end %>
|
||||
|
||||
<title><%= t("bigbluebutton") %></title>
|
||||
<meta property="og:title" content="<%= t("bigbluebutton", locale: :en) %>" />
|
||||
<title><%= yield(:page_title).present? ? yield(:page_title) : t("bigbluebutton") %></title>
|
||||
<meta property="og:title" content="<%= yield(:page_title).present? ? yield(:page_title) : t("bigbluebutton") %>" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:description" content="<%= t("landing.about", href: "Greenlight", locale: :en) %>" />
|
||||
<meta property="og:description" content="<%= yield(:page_desc).present? ? yield(:page_desc) : t("landing.about", href: "Greenlight", locale: :en) %>" />
|
||||
<meta property="og:url" content="<%= request.base_url %>" />
|
||||
<meta property="og:image" content="<%= logo_image %>" />
|
||||
|
||||
<meta name="viewport" content= "width=device-width, user-scalable=no">
|
||||
<%= csrf_meta_tags %>
|
||||
|
||||
@ -48,6 +47,8 @@
|
||||
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
||||
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
|
||||
|
||||
<%= favicon_link_tag asset_path('favicon.ico') %>
|
||||
|
||||
<!-- Primary color styling -->
|
||||
<%= stylesheet_link_tag themes_primary_path %>
|
||||
|
||||
|
@ -50,6 +50,11 @@
|
||||
<a href="" data-toggle="modal" data-target="#createRoomModal" class="update-room dropdown-item" data-settings-path="<%= room_settings_path(room) %>">
|
||||
<i class="dropdown-icon fas fa-cog"></i> <%= t("room.settings") %>
|
||||
</a>
|
||||
<% if preupload_allowed? %>
|
||||
<a href="" data-toggle="modal" data-target="#preuploadPresentationModal" class="preupload-room dropdown-item" data-path="<%= preupload_presentation_path(room) %>" data-settings-path="<%= current_presentation_path(room) %>" data-remove="<%= remove_presentation_path(room) %>">
|
||||
<i class="dropdown-icon fas fa-file-upload"></i> <%= t("room.add_presentation") %>
|
||||
</a>
|
||||
<% end %>
|
||||
<% if shared_access_allowed %>
|
||||
<a href="" data-toggle="modal" data-target="#shareRoomModal" class="share-room dropdown-item" data-path="<%= room_shared_access_path(room) %>" data-users-path="<%= room_shared_users_path(room) %>">
|
||||
<i class="dropdown-icon fas fa-users"></i> <%= t("room.share") %>
|
||||
|
@ -18,19 +18,19 @@
|
||||
<div class="row pt-9">
|
||||
<div class="col-lg-12 col-sm-12">
|
||||
<h4 class="text-left"><%= t("room.invited") %></h4>
|
||||
<h1 class="display-3 text-left mb-3 font-weight-400"><%= @room.name %></h1>
|
||||
<h1 class="display-3 text-left mb-3 font-weight-400"><%= title(@room.name) %></h1>
|
||||
<hr class="mt-2 float-left w-25">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-6 col-sm-12 form-inline mb-5 align-top">
|
||||
<div class="col-lg-6 col-md-6 col-sm-12 mb-5">
|
||||
<% if @room.owner.image.blank? %>
|
||||
<span class="avatar"><%= @room.owner.name.first %></span>
|
||||
<% else %>
|
||||
<span class="avatar" style="background-image: url(<%= @room.owner.image %>)"></span>
|
||||
<% end %>
|
||||
<h5 class="font-weight-normal ml-4 mt-3"><%= @room.owner.name %> (<%= t("room.owner") %>)</h5>
|
||||
<h5 id="room-owner-name" class="font-weight-normal ml-4 mt-3 d-inline-block"><%= @room.owner.name %> (<%= t("room.owner") %>)</h5>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
@ -40,6 +40,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% if render_recordings %>
|
||||
<% recording = room_configuration("Room Configuration Recording") %>
|
||||
<% if render_recordings && recording != "disabled" %>
|
||||
<%= render "shared/sessions", recordings: @public_recordings, pagy: @pagy, only_public: true, user_recordings: false, title: t("room.recordings") %>
|
||||
<% end %>
|
||||
|
@ -13,6 +13,8 @@
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
%>
|
||||
|
||||
<% content_for(:page_desc) { t("room.invitation_description", name: @room.name) } %>
|
||||
|
||||
<% valid_access_code = @room.access_code.nil? || @room.access_code.empty? || @room.access_code == session[:access_code] %>
|
||||
<%= render 'rooms/components/room_event', render_recordings: valid_access_code do %>
|
||||
<% if room_authentication_required %>
|
||||
@ -44,11 +46,17 @@
|
||||
autofocus: true
|
||||
%>
|
||||
<span class="input-group-append">
|
||||
<button type="submit" class="btn btn-primary btn-sm px-7 form-control join-form">
|
||||
<button id="room-join" type="submit" class="btn btn-primary btn-sm px-7 form-control join-form">
|
||||
<%= (!@room_running && @anyone_can_start) ? t("room.start") : t("room.join") %>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<% if recording_consent_required? && @room.recording_enabled? %>
|
||||
<label class="custom-control custom-checkbox">
|
||||
<input id="joiner-consent" type="checkbox" class="custom-control-input" required>
|
||||
<h4 class="text-left text-danger mt-4 custom-control-label"><%= t("room.recording_present") %></h4>
|
||||
</label>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
@ -24,11 +24,10 @@
|
||||
<div class="row pt-7 pt-sm-9">
|
||||
<div class="col-lg-8 col-sm-12">
|
||||
<div id="room-title" class="display-3 form-inline <%= 'edit_hover_class' if current_user.main_room != @room %>" data-path="<%= update_settings_path(@room) %>">
|
||||
<h1 contenteditable=false id="user-text" class="display-3 text-left mb-3 font-weight-400"><%= title(@room.name) %></h1>
|
||||
<% if current_user.main_room == @room %>
|
||||
<h1 contenteditable=false id="user-text" class="display-3 text-left mb-3 font-weight-400"><%= @room.name %></h1>
|
||||
<a class="disable-click"><i class="fas fa-home align-top home-indicator ml-2"></i></a>
|
||||
<% else %>
|
||||
<h1 contenteditable=false id="user-text" class="display-3 text-left mb-3 font-weight-400"><%= @room.name %></h1>
|
||||
<a><i id="edit-room" class="fa fa-edit align-top home-indicator ml-2" data-edit-room="<%= @room.uid %>"></i></a>
|
||||
<% end %>
|
||||
</div>
|
||||
@ -104,12 +103,19 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render "shared/sessions", recordings: @recordings, pagy: @pagy, only_public: false, shared_room: @shared_room, user_recordings: false, title: t("room.recordings")%>
|
||||
<% recording = room_configuration("Room Configuration Recording") %>
|
||||
<% if recording != "disabled" %>
|
||||
<%= render "shared/sessions", recordings: @recordings, pagy: @pagy, only_public: false, shared_room: @shared_room, user_recordings: false, title: t("room.recordings")%>
|
||||
<% end %>
|
||||
|
||||
<%= render "shared/modals/delete_room_modal" %>
|
||||
|
||||
<%= render "shared/modals/create_room_modal" %>
|
||||
|
||||
<% if preupload_allowed? %>
|
||||
<%= render "shared/modals/preupload_presentation_modal" %>
|
||||
<% end %>
|
||||
|
||||
<% if shared_access_allowed %>
|
||||
<%= render "shared/modals/share_room_modal" %>
|
||||
<%= render "shared/modals/remove_access_modal" %>
|
||||
|
@ -27,7 +27,7 @@
|
||||
<% elsif key.eql? "maintenance" %>
|
||||
<div class="alert alert-info alert-dismissible text-center mb-0">
|
||||
<%= value %>
|
||||
<button id="maintenance-close" type="button" data-date="<%= Rails.configuration.maintenance_window %>" class="close" data-dismiss="alert">×</button>
|
||||
<button id="maintenance-close" type="button" data-date="<%= URI.encode(value) %>" class="close" data-dismiss="alert">×</button>
|
||||
</div>
|
||||
<% elsif key.eql? "info" %>
|
||||
<div class="alert alert-info alert-dismissible text-center mb-0">
|
||||
|
@ -31,7 +31,9 @@
|
||||
<i class="fas fa-home pr-1 "></i><span class="d-none d-sm-inline-block"><%= t("header.dropdown.home") %></span>
|
||||
<% end %>
|
||||
|
||||
<% if current_user.role.get_permission("can_create_rooms") && !current_user.has_role?(:super_admin) %>
|
||||
<% recording = room_configuration("Room Configuration Recording") %>
|
||||
<% if current_user.role.get_permission("can_create_rooms") && !current_user.has_role?(:super_admin) &&
|
||||
recording != "disabled" %>
|
||||
<% all_rec_page = params[:controller] == "users" && params[:action] == "recordings" ? "active" : "" %>
|
||||
<%= link_to get_user_recordings_path(current_user), class: "px-3 mx-1 mt-1 header-nav #{all_rec_page}" do %>
|
||||
<i class="fas fa-video pr-1"></i><span class="d-none d-sm-inline-block"><%= t("header.all_recordings") %></span>
|
||||
|
@ -16,13 +16,14 @@
|
||||
<tr>
|
||||
<td>
|
||||
<div id="recording-title" class="edit_hover_class" data-recordid="<%= recording[:recordID] %>" data-room-uid="<%= room_uid_from_bbb(recording[:meetingID]) %>" data-path="<%= rename_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]) %>">
|
||||
<span id="recording-text" title="<%= recording[:name] %>">
|
||||
<% if recording[:metadata][:name] %>
|
||||
<% if recording[:metadata][:name] %>
|
||||
<span id="recording-text" title="<%= recording[:metadata][:name] %>">
|
||||
<%= recording[:metadata][:name] %>
|
||||
<% else %>
|
||||
<% else %>
|
||||
<span id="recording-text" title="<%= recording[:name] %>">
|
||||
<%= recording[:name] %>
|
||||
<% end %>
|
||||
</span>
|
||||
<% end %>
|
||||
</span>
|
||||
</div>
|
||||
<div class="small text-muted">
|
||||
<%= t("recording.recorded_on", date: recording_date(recording[:startTime])) %>
|
||||
|
@ -16,13 +16,14 @@
|
||||
<tr>
|
||||
<td>
|
||||
<div id="recording-title" class="edit_hover_class" data-recordid="<%= recording[:recordID] %>" data-room-uid="<%= room_uid_from_bbb(recording[:meetingID]) %>" data-path="<%= rename_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]) %>">
|
||||
<span id='recording-text' title="<%= recording[:name] %>">
|
||||
<% if recording[:metadata][:name] %>
|
||||
<% if recording[:metadata][:name] %>
|
||||
<span id='recording-text' title="<%= recording[:metadata][:name] %>">
|
||||
<%= recording[:metadata][:name] %>
|
||||
<% else %>
|
||||
<% else %>
|
||||
<span id='recording-text' title="<%= recording[:name] %>">
|
||||
<%= recording[:name] %>
|
||||
<% end %>
|
||||
</span>
|
||||
<% end %>
|
||||
</span>
|
||||
<a><i id="edit-record" class="fa fa-edit align-top ml-2" data-edit-recordid="<%= recording[:recordID] %>"></i></a>
|
||||
</div>
|
||||
<div class="small text-muted">
|
||||
|
@ -16,18 +16,10 @@
|
||||
<div class="row mt-2">
|
||||
<% if search %>
|
||||
<div class="col-md-6">
|
||||
<p class="subtitle"><%= subtitle %></p>
|
||||
<p class="subtitle"><%= title(subtitle) %></p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 mb-4">
|
||||
<% if admin_invite_registration %>
|
||||
<div id="invite-user" class="d-inline-block float-right ml-3">
|
||||
<%= link_to "#inviteModal", :class => "btn btn-primary", "data-toggle": "modal" do %>
|
||||
<%= t("administrator.users.invite") %> <i class="fas fa-paper-plane ml-1"></i>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div id="search-bar" class="d-inline-block float-right">
|
||||
<div class="input-group">
|
||||
<input id="search-input" type="text" class="form-control" placeholder="<%= t("settings.search") %>..." value="<%= @search %>">
|
||||
@ -46,7 +38,7 @@
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="col-12">
|
||||
<p class="subtitle"><%= subtitle %></p>
|
||||
<p class="subtitle"><%= title(subtitle) %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
@ -69,7 +69,6 @@
|
||||
<span class="custom-switch-indicator float-right cursor-pointer"></span>
|
||||
</label>
|
||||
<% end %>
|
||||
|
||||
<% moderator = room_configuration("Room Configuration All Join Moderator") %>
|
||||
<% if moderator != "disabled" %>
|
||||
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%= "enabled-setting" if moderator == "enabled" %>">
|
||||
@ -78,7 +77,14 @@
|
||||
<span class="custom-switch-indicator float-right cursor-pointer"></span>
|
||||
</label>
|
||||
<% end %>
|
||||
|
||||
<% recording = room_configuration("Room Configuration Recording") %>
|
||||
<% if recording_consent_required? && recording != "disabled" %>
|
||||
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%= "enabled-setting" if recording == "enabled" %>">
|
||||
<span class="custom-switch-description"><%= t("modal.room_settings.recording")%></span>
|
||||
<%= f.check_box :recording, class: "not-running-only custom-switch-input", data: { default: recording == "enabled" }, checked: false %>
|
||||
<span class="custom-switch-indicator not-running-only float-right cursor-pointer"></span>
|
||||
</label>
|
||||
<% end %>
|
||||
<label id="auto-join-label" class="create-only custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block">
|
||||
<span class="custom-switch-description"><%= t("modal.create_room.auto_join") %></span>
|
||||
<%= f.check_box :auto_join, class: "custom-switch-input", checked: false %>
|
||||
|
@ -0,0 +1,52 @@
|
||||
<%
|
||||
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
|
||||
# This program is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
# You should have received a copy of the GNU Lesser General Public License along
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
%>
|
||||
|
||||
<div class="modal fade" id="preuploadPresentationModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content text-center">
|
||||
<div class="modal-body">
|
||||
<div class="card-body p-sm-6">
|
||||
<div class="card-title">
|
||||
<h3><%= t("modal.preupload.title") %></h3>
|
||||
</div>
|
||||
|
||||
<div id="current-presentation" class='mt-5 text-left'>
|
||||
<label class='form-label'><%= t('modal.preupload.current') %></label>
|
||||
<div class='list-group-item text-left'>
|
||||
<span id="presentation-name"></span>
|
||||
<span id="remove-presentation" class="text-primary float-right cursor-pointer"><i class="fas fa-trash-alt"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-5">
|
||||
<%= form_for(:room, method: :post, url: "/") do |f| %>
|
||||
<p id="invalid-file-type" class="text-danger"><%= t("modal.preupload.invalid") %></p>
|
||||
<div class="input-group mb-3">
|
||||
<div class="custom-file text-left">
|
||||
<%= f.label :presentation, t("modal.preupload.choose", type: allowed_file_types), id:"presentation-upload-label", class: "custom-file-label", "data-placeholder": t("modal.preupload.choose", type: allowed_file_types) %>
|
||||
<%= f.file_field :presentation, id: "presentation-upload", class: "custom-file-input cursor-pointer", accept: allowed_file_types, required: "true" %>
|
||||
</div>
|
||||
</div>
|
||||
<%= f.submit t("modal.preupload.change"), id: "change-pres", class: "btn btn-primary btn-block" %>
|
||||
<%= f.submit t("modal.preupload.use"), id: "use-pres", class: "btn btn-primary btn-block" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<p><%= t("modal.preupload.footer") %></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -23,7 +23,6 @@
|
||||
</div>
|
||||
|
||||
<%= button_to "/", method: :delete, id: "remove-shared-confirm", class: "btn btn-danger my-1 btn-del-room" do %>
|
||||
<%= hidden_field_tag :user_id, current_user.id %>
|
||||
<%= t("modal.remove_shared.delete") %>
|
||||
<% end %>
|
||||
|
||||
|
Reference in New Issue
Block a user