Restructure organization settings and permissions.

This restructures organization settings and permissions to be
more accurately grouped and for the permissions page to not be too
long.

CHANGES:

PROFILE:
    (this was split out)
    organization-profile-admin.handlebars:
        form #1:
            name
            description
            (SUBMIT)
        avatar:
            (UPLOAD)
            (DELETE)

SETTINGS:
    organization-settings-admin.handlebars:
        language (mostly untouched)
        message editing:
            time limit/history/retention
        message feed:
            mandatory-topics
            preview images
            preview websites

PERMISSIONS:
    organization-permissions-admin.handlebars
    (mostly stuff was removed)
    Joining:
        restrict domains
        require invite
    User Identity:
        name changes
        email changes
    Streams/Emoji:
        creating streams:
            waiting period (ADDED)
        adding emojis
    (SUBMIT) for whole panel

The profile group (name, description, avatar) were split into a new
page that did not previously exist, and the permissions was stripped
of message settings (message editing, message feed), but keeping the
"waiting period" input and putting it in the "Streams & custom emoji"
section.

Fixes: #5844.
This commit is contained in:
Brock Whittaker
2017-08-17 16:23:55 -07:00
committed by Tim Abbott
parent e74f509b32
commit dba09c979c
16 changed files with 409 additions and 282 deletions

View File

@@ -19,6 +19,10 @@ casper.waitForSelector('#settings_overlay_container.show', function () {
casper.test.assertUrlMatch(/^http:\/\/[^/]+\/#organization/, 'URL suggests we are on organization page');
});
casper.then(function () {
casper.click("li[data-section='organization-settings']");
});
// Test changing notifications stream
casper.then(function () {
casper.test.info('Changing notifications stream to Verona by filtering with "verona"');
@@ -241,7 +245,7 @@ casper.then(function () {
// Test uploading realm icon image
casper.then(function () {
casper.click("li[data-section='organization-settings']");
casper.click("li[data-section='organization-profile']");
var selector = 'img#realm-settings-icon[src^="https://secure.gravatar.com/avatar/"]';
casper.waitUntilVisible(selector, function () {
casper.test.assertEqual(casper.visible('#realm_icon_delete_button'), false);
@@ -257,7 +261,7 @@ casper.then(function () {
// Test deleting realm icon image
casper.then(function () {
casper.click("li[data-section='organization-settings']");
casper.click("li[data-section='organization-profile']");
casper.click("#realm_icon_delete_button");
casper.test.assertEqual(casper.visible('#realm_icon_delete_button'), true);
casper.waitWhileVisible('#realm_icon_delete_button', function () {

View File

@@ -85,13 +85,13 @@ casper.waitForSelector('#settings_overlay_container.show', function () {
});
casper.then(function () {
casper.click("li[data-section='organization-permissions']");
casper.click("li[data-section='organization-settings']");
});
// deactivate "allow message editing"
casper.waitUntilVisible('input[type="checkbox"][id="id_realm_allow_message_editing"] + span', function () {
casper.click('input[type="checkbox"][id="id_realm_allow_message_editing"] + span');
casper.click('form.org-permissions-form button.button');
casper.click('form.org-settings-form button.button');
});
casper.then(function () {
@@ -151,9 +151,14 @@ casper.then(function () {
casper.click('#settings-dropdown');
casper.click('a[href^="#organization"]');
});
casper.waitUntilVisible("li[data-section='organization-settings']", function () {
casper.click("li[data-section='organization-settings']");
});
casper.waitUntilVisible('input[type="checkbox"][id="id_realm_allow_message_editing"] + span', function () {
casper.click('input[type="checkbox"][id="id_realm_allow_message_editing"] + span');
casper.click('form.org-permissions-form button.button');
casper.click('form.org-settings-form button.button');
casper.waitUntilVisible('#admin-realm-message-editing-status', function () {
casper.test.assertSelectorHasText('#admin-realm-message-editing-status', 'Users can now edit topics for all their messages, and the content of messages which are less than 10 minutes old.');
casper.test.assertEval(function () {
@@ -213,7 +218,7 @@ casper.waitUntilVisible('input[type="checkbox"][id="id_realm_allow_message_editi
$('input[type="text"][id="id_realm_message_content_edit_limit_minutes"]').val('4');
});
casper.click('input[type="checkbox"][id="id_realm_allow_message_editing"] + span');
casper.click('form.org-permissions-form button.button');
casper.click('form.org-settings-form button.button');
});
casper.then(function () {
@@ -232,7 +237,7 @@ casper.then(function () {
// allow message editing again, and check that the old edit limit is still there
casper.waitUntilVisible('input[type="checkbox"][id="id_realm_allow_message_editing"] + span', function () {
casper.click('input[type="checkbox"][id="id_realm_allow_message_editing"] + span');
casper.click('form.org-permissions-form button.button');
casper.click('form.org-settings-form button.button');
});
});
@@ -254,7 +259,7 @@ casper.then(function () {
casper.evaluate(function () {
$('input[type="text"][id="id_realm_message_content_edit_limit_minutes"]').val('0');
});
casper.click('form.org-permissions-form button.button');
casper.click('form.org-settings-form button.button');
});
});
@@ -277,7 +282,7 @@ casper.then(function () {
$('input[type="text"][id="id_realm_message_content_edit_limit_minutes"]').val('moo');
});
casper.click('input[type="checkbox"][id="id_realm_allow_message_editing"] + span');
casper.click('form.org-permissions-form button.button');
casper.click('form.org-settings-form button.button');
});
});

View File

@@ -157,7 +157,7 @@ function test_realms_domain_modal(add_realm_domain) {
assert.equal(info.text(), 'no can do');
}
function test_submit_settings_form(submit_form) {
function test_submit_profile_form(submit_form) {
var ev = {
preventDefault: noop,
stopPropagation: noop,
@@ -165,12 +165,9 @@ function test_submit_settings_form(submit_form) {
$('#id_realm_name').val('Acme');
$('#id_realm_description').val('makes widgets');
$('#id_realm_default_language').val('fr');
$('#id_realm_waiting_period_threshold').val('55');
var patched;
var success_callback;
var error_callback;
channel.patch = function (req) {
patched = true;
@@ -180,74 +177,53 @@ function test_submit_settings_form(submit_form) {
assert.equal(data.name, '"Acme"');
assert.equal(data.description, '"makes widgets"');
assert.equal(data.default_language, '"fr"');
assert.equal(data.waiting_period_threshold, '55');
success_callback = req.success;
error_callback = req.error;
};
submit_form(ev);
assert(patched);
var response_data = {
waiting_period_threshold: 55,
name: 'Acme',
};
success_callback(response_data);
assert.equal($('#admin-realm-name-status').val(),
'translated: Name changed!');
assert.equal($('#admin-realm-waiting-period-threshold-status').val(),
'translated: Waiting period threshold changed!');
// TODO: change the code to have a better place to report status.
var status_elem = $('#admin-realm-name-status');
success_callback({});
assert.equal(status_elem.val(),
'translated: No changes to save!');
error_callback({});
assert.equal(status_elem.val(),
'translated: Failed');
}
function test_submit_permissions_form(submit_form) {
function test_submit_settings_form(submit_form) {
var ev = {
preventDefault: noop,
stopPropagation: noop,
};
$('#id_realm_add_emoji_by_admins_only').prop('checked', true);
$('#id_realm_default_language').val('fr');
var patched;
var success_callback;
var error_callback;
channel.patch = function (req) {
patched = true;
assert.equal(req.url, '/json/realm');
var data = req.data;
assert.equal(data.add_emoji_by_admins_only, 'true');
assert.equal(data.default_language, '"fr"');
success_callback = req.success;
error_callback = req.error;
};
submit_form(ev);
assert(patched);
var response_data = {
add_emoji_by_admins_only: true,
allow_message_editing: true,
message_content_edit_limit_seconds: 210,
};
success_callback(response_data);
assert.equal($('#admin-realm-add-emoji-by-admins-only-status').val(),
'translated: Only administrators may now add new emoji!');
success_callback(response_data);
var editing_status = $('#admin-realm-message-editing-status').val();
assert(editing_status.indexOf('content of messages which are less than') > 0);
@@ -269,6 +245,47 @@ function test_submit_permissions_form(submit_form) {
assert.equal($('#admin-realm-message-editing-status').val(),
'translated: Users can no longer edit their past messages!');
}
function test_submit_permissions_form(submit_form) {
var ev = {
preventDefault: noop,
stopPropagation: noop,
};
$('#id_realm_add_emoji_by_admins_only').prop('checked', true);
$('#id_realm_waiting_period_threshold').val('55');
var patched;
var success_callback;
var error_callback;
channel.patch = function (req) {
patched = true;
assert.equal(req.url, '/json/realm');
var data = req.data;
assert.equal(data.add_emoji_by_admins_only, 'true');
assert.equal(data.waiting_period_threshold, '55');
success_callback = req.success;
error_callback = req.error;
};
submit_form(ev);
assert(patched);
var response_data = {
waiting_period_threshold: 55,
add_emoji_by_admins_only: true,
};
success_callback(response_data);
assert.equal($('#admin-realm-add-emoji-by-admins-only-status').val(),
'translated: Only administrators may now add new emoji!');
assert.equal($('#admin-realm-waiting-period-threshold-status').val(),
'translated: Waiting period threshold changed!');
// TODO: change the code to have a better place to report status.
var status_elem = $('#admin-realm-restricted-to-domain-status');
@@ -449,6 +466,7 @@ function test_change_allow_subdomains(change_allow_subdomains) {
var submit_settings_form;
var submit_permissions_form;
var submit_profile_form;
$('.organization').on = function (action, selector, f) {
assert.equal(action, 'submit');
if (selector === 'form.org-settings-form') {
@@ -457,6 +475,9 @@ function test_change_allow_subdomains(change_allow_subdomains) {
if (selector === 'form.org-permissions-form') {
submit_permissions_form = f;
}
if (selector === 'form.org-profile-form') {
submit_profile_form = f;
}
};
var change_allow_subdomains;
@@ -480,6 +501,7 @@ function test_change_allow_subdomains(change_allow_subdomains) {
test_realms_domain_modal(callbacks.add_realm_domain);
test_submit_profile_form(submit_profile_form);
test_submit_settings_form(submit_settings_form);
test_submit_permissions_form(submit_permissions_form);
test_upload_realm_icon(upload_realm_icon);

View File

@@ -66,6 +66,9 @@ exports.make_zjquery = function () {
};
},
empty: noop,
eq: function () {
return self;
},
expectOne: function () {
// silently do nothing
return self;

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

View File

@@ -8,6 +8,8 @@ exports.show_or_hide_menu_item = function () {
item.find("span").text(i18n.t("Manage organization"));
} else {
item.find("span").text(i18n.t("Organization settings"));
$(".organization-box [data-name='organization-profile']")
.find("input, textarea, button, select").attr("disabled", true);
$(".organization-box [data-name='organization-settings']")
.find("input, textarea, button, select").attr("disabled", true);
$(".organization-box [data-name='organization-permissions']")
@@ -67,7 +69,7 @@ function _setup_page() {
var hash_sequence = window.location.hash.split(/\//);
if (/#*(organization)/.test(hash_sequence[0])) {
tab = hash_sequence[1];
return tab || "organization-settings";
return tab || "organization-profile";
}
return tab;
}());

View File

@@ -8,6 +8,7 @@ exports.load_admin_section = function (name) {
var section;
switch (name) {
case 'organization-profile':
case 'organization-settings':
case 'organization-permissions':
case 'auth-methods':

View File

@@ -782,7 +782,7 @@ $(function () {
if (key === "organization") {
$("li.admin").show();
if (!payload.dont_switch_tab) {
$("li[data-section='organization-settings']").click();
$("li[data-section='organization-profile']").click();
}
} else {
$("li:not(.admin)").show();

View File

@@ -60,6 +60,7 @@ function _setup_page() {
"uploaded-files": i18n.t("Uploaded files"),
"muted-topics": i18n.t("Muted topics"),
"zulip-labs": i18n.t("Zulip labs"),
"organization-profile": i18n.t("Organization profile"),
"organization-settings": i18n.t("Organization settings"),
"organization-permissions": i18n.t("Organization permissions"),
"emoji-settings": i18n.t("Emoji settings"),

View File

@@ -183,7 +183,7 @@ function _set_up() {
// create property_types object
var property_types = {
settings: {
profile: {
name: {
type: 'text',
msg: i18n.t("Name changed!"),
@@ -192,41 +192,22 @@ function _set_up() {
type: 'text',
msg: i18n.t("Description changed!"),
},
},
settings: {
default_language: {
type: 'text',
msg: i18n.t("Default language changed!"),
},
},
permissions: {
add_emoji_by_admins_only: {
type: 'bool',
checked_msg: i18n.t("Only administrators may now add new emoji!"),
unchecked_msg: i18n.t("Any user may now add new emoji!"),
},
allow_edit_history: {
type: 'bool',
checked_msg: i18n.t("Users can view message edit history!"),
unchecked_msg: i18n.t("Users can no longer view message edit history!"),
},
create_stream_by_admins_only: {
mandatory_topics: {
type: 'bool',
checked_msg: i18n.t("Only administrators may now create new streams!"),
unchecked_msg: i18n.t("Any user may now create new streams!"),
},
email_changes_disabled: {
type: 'bool',
checked_msg: i18n.t("Users cannot change their email!"),
unchecked_msg: i18n.t("Users may now change their email!"),
},
invite_required: {
type: 'bool',
checked_msg: i18n.t("New users must be invited by e-mail!"),
unchecked_msg: i18n.t("New users may sign up online!"),
},
invite_by_admins_only: {
type: 'bool',
checked_msg: i18n.t("New users must be invited by an admin!"),
unchecked_msg: i18n.t("Any user may now invite new users!"),
checked_msg: i18n.t("Topics are required in messages to streams!"),
unchecked_msg: i18n.t("Topics are not required in messages to streams!"),
},
inline_image_preview: {
type: 'bool',
@@ -238,20 +219,43 @@ function _set_up() {
checked_msg: i18n.t("Previews for linked websites will be shown!"),
unchecked_msg: i18n.t("Previews for linked websites will not be shown!"),
},
name_changes_disabled: {
type: 'bool',
checked_msg: i18n.t("Users cannot change their name!"),
unchecked_msg: i18n.t("Users may now change their name!"),
},
permissions: {
restricted_to_domain: {
type: 'bool',
checked_msg: i18n.t("New user e-mails now restricted to certain domains!"),
unchecked_msg: i18n.t("New users may have arbitrary e-mails!"),
},
mandatory_topics: {
invite_required: {
type: 'bool',
checked_msg: i18n.t("Topics are required in messages to streams"),
unchecked_msg: i18n.t("Topics are not required in messages to streams"),
checked_msg: i18n.t("New users must be invited by e-mail!"),
unchecked_msg: i18n.t("New users may sign up online!"),
},
invite_by_admins_only: {
type: 'bool',
checked_msg: i18n.t("New users must be invited by an admin!"),
unchecked_msg: i18n.t("Any user may now invite new users!"),
},
name_changes_disabled: {
type: 'bool',
checked_msg: i18n.t("Users cannot change their name!"),
unchecked_msg: i18n.t("Users may now change their name!"),
},
email_changes_disabled: {
type: 'bool',
checked_msg: i18n.t("Users cannot change their email!"),
unchecked_msg: i18n.t("Users may now change their email!"),
},
create_stream_by_admins_only: {
type: 'bool',
checked_msg: i18n.t("Only administrators may now create new streams!"),
unchecked_msg: i18n.t("Any user may now create new streams!"),
},
add_emoji_by_admins_only: {
type: 'bool',
checked_msg: i18n.t("Only administrators may now add new emoji!"),
unchecked_msg: i18n.t("Any user may now add new emoji!"),
},
waiting_period_threshold: {
type: 'integer',
@@ -272,8 +276,7 @@ function _set_up() {
return;
}
if (field.type === 'integer') {
data[k] = JSON.stringify(parseInt($('#id_realm_'+k).val().trim(), 10));
return;
data[k] = JSON.stringify(parseInt($("#id_realm_"+k).val().trim(), 10));
}
});
return data;
@@ -333,63 +336,21 @@ function _set_up() {
});
$(".organization").on("submit", "form.org-settings-form", function (e) {
e.preventDefault();
e.stopPropagation();
_.each(property_types.settings, function (v, k) {
property_type_status_element(k).hide();
});
var name_status = $("#admin-realm-name-status").expectOne();
var waiting_period_threshold_status = $("#admin-realm-waiting-period-threshold-status").expectOne();
name_status.hide();
waiting_period_threshold_status.hide();
e.preventDefault();
e.stopPropagation();
var url = "/json/realm";
var data = populate_data_for_request({}, 'settings');
channel.patch({
url: url,
data: data,
success: function (response_data) {
process_response_data(response_data, 'settings');
if (response_data.waiting_period_threshold !== undefined) {
if (response_data.waiting_period_threshold >= 0) {
ui_report.success(i18n.t("Waiting period threshold changed!"), waiting_period_threshold_status);
}
}
// Check if no changes made
var no_changes_made = true;
for (var key in response_data) {
if (['msg', 'result'].indexOf(key) < 0) {
no_changes_made = false;
}
}
if (no_changes_made) {
ui_report.success(i18n.t("No changes to save!"), name_status);
}
},
error: function (xhr) {
ui_report.error(i18n.t("Failed"), xhr, name_status);
},
});
});
$(".organization").on("submit", "form.org-permissions-form", function (e) {
_.each(property_types.permissions, function (v, k) {
property_type_status_element(k).hide();
});
var restricted_to_domain_status = $("#admin-realm-restricted-to-domain-status").expectOne();
var message_editing_status = $("#admin-realm-message-editing-status").expectOne();
restricted_to_domain_status.hide();
message_editing_status.hide();
// grab the first alert available and use it for the status.
var $alerts = $(".settings-section.show .alert").hide();
// grab the first alert available and use it for the status.
var status = $("#admin-realm-notifications-stream-status");
e.preventDefault();
e.stopPropagation();
var new_allow_message_editing = $("#id_realm_allow_message_editing").prop("checked");
var new_message_content_edit_limit_minutes = $("#id_realm_message_content_edit_limit_minutes").val();
var new_message_retention_days = $("#id_realm_message_retention_days").val();
var new_allow_message_editing = $("#id_realm_allow_message_editing").prop("checked");
// If allow_message_editing is unchecked, message_content_edit_limit_minutes
// is irrelevant. Hence if allow_message_editing is unchecked, and
@@ -403,24 +364,21 @@ function _set_up() {
new_message_content_edit_limit_minutes = 10;
}
}
if (parseInt(new_message_retention_days, 10).toString() !==
new_message_retention_days && new_message_retention_days !== "") {
new_message_retention_days = "";
}
var url = "/json/realm";
var data = {
var data = {};
data = populate_data_for_request({
allow_message_editing: JSON.stringify(new_allow_message_editing),
message_content_edit_limit_seconds:
JSON.stringify(parseInt(new_message_content_edit_limit_minutes, 10) * 60),
message_retention_days: new_message_retention_days !== "" ? JSON.stringify(parseInt(new_message_retention_days, 10)) : null,
};
data = populate_data_for_request(data, 'permissions');
}, 'settings');
channel.patch({
url: url,
data: data,
success: function (response_data) {
process_response_data(response_data, 'permissions');
$alerts.hide();
if (response_data.allow_message_editing !== undefined) {
// We expect message_content_edit_limit_seconds was sent in the
// response as well
@@ -443,6 +401,8 @@ function _set_up() {
// in this function, so update the field just in case
$("#id_realm_message_content_edit_limit_minutes").val(data_message_content_edit_limit_minutes);
}
process_response_data(response_data, 'settings');
// Check if no changes made
var no_changes_made = true;
for (var key in response_data) {
@@ -451,14 +411,106 @@ function _set_up() {
}
}
if (no_changes_made) {
ui_report.success(i18n.t("No changes to save!"), restricted_to_domain_status);
ui_report.success(i18n.t("No changes to save!"), status);
}
},
error: function (xhr) {
ui_report.error(i18n.t("Failed"), xhr, restricted_to_domain_status);
$alerts.hide();
ui_report.error(i18n.t("Failed"), xhr, status);
},
});
});
$(".organization").on("submit", "form.org-permissions-form", function (e) {
var $alerts = $(".settings-section.show .alert").hide();
// grab the first alert available and use it for the status.
var status = $("#admin-realm-restricted-to-domain-status");
var waiting_period_threshold_status = $("#admin-realm-waiting-period-threshold-status").expectOne();
status.hide();
e.preventDefault();
e.stopPropagation();
var new_message_retention_days = $("#id_realm_message_retention_days").val();
if (parseInt(new_message_retention_days, 10).toString() !==
new_message_retention_days && new_message_retention_days !== "") {
new_message_retention_days = "";
}
// take the existing object and apply the rest of the properties.
var data = populate_data_for_request({
message_retention_days: new_message_retention_days !== "" ? JSON.stringify(parseInt(new_message_retention_days, 10)) : null,
}, 'permissions');
channel.patch({
url: "/json/realm",
data: data,
success: function (response_data) {
$alerts.hide();
if (response_data.waiting_period_threshold !== undefined) {
if (response_data.waiting_period_threshold >= 0) {
ui_report.success(i18n.t("Waiting period threshold changed!"), waiting_period_threshold_status);
}
}
process_response_data(response_data, 'permissions');
// Check if no changes made
var no_changes_made = true;
for (var key in response_data) {
if (['msg', 'result'].indexOf(key) < 0) {
no_changes_made = false;
}
}
if (no_changes_made) {
ui_report.success(i18n.t("No changes to save!"), status);
}
},
error: function (xhr) {
$alerts.hide();
ui_report.error(i18n.t("Failed"), xhr, status);
},
});
});
$(".organization").on("submit", "form.org-profile-form", function (e) {
e.preventDefault();
e.stopPropagation();
var $alerts = $(".settings-section.show .alert");
// grab the first alert available and use it for the status.
var status = $("#admin-realm-name-status");
var data = populate_data_for_request({}, 'profile');
channel.patch({
url: "/json/realm",
data: data,
success: function (response_data) {
$alerts.hide();
process_response_data(response_data, 'profile');
// Check if no changes made
var no_changes_made = true;
for (var key in response_data) {
if (['msg', 'result'].indexOf(key) < 0) {
no_changes_made = false;
}
}
if (no_changes_made) {
ui_report.success(i18n.t("No changes to save!"), status);
}
},
error: function (xhr) {
ui_report.error(i18n.t("Failed"), xhr, status);
},
});
});
$(".organization").on("submit", "form.org-authentications-form", function (e) {
var authentication_methods_status = $("#admin-realm-authentication-methods-status").expectOne();

View File

@@ -69,6 +69,10 @@ label {
margin: 6px 0px 0px 0px;
}
.new-style .button ul {
text-align: left;
}
/* this is because the input[type=text] is also 200px wide but has
12px of padding and 2px worth of borders. These don't apply to
buttons however. */

View File

@@ -4,6 +4,7 @@
{{ partial "deactivation-stream-modal" }}
{{ partial "realm-domains-modal" }}
{{ partial "organization-profile-admin" }}
{{ partial "organization-settings-admin" }}
{{ partial "organization-permissions-admin" }}

View File

@@ -5,15 +5,11 @@
<div class="alert" id="admin-realm-restricted-to-domain-status"></div>
<div class="alert" id="admin-realm-invite-required-status"></div>
<div class="alert" id="admin-realm-invite-by-admins-only-status"></div>
<div class="alert" id="admin-realm-inline-image-preview-status"></div>
<div class="alert" id="admin-realm-inline-url-embed-preview-status"></div>
<div class="alert" id="admin-realm-create-stream-by-admins-only-status"></div>
<div class="alert" id="admin-realm-add-emoji-by-admins-only-status"></div>
<div class="alert" id="admin-realm-allow-edit-history-status"></div>
<div class="alert" id="admin-realm-message-editing-status"></div>
<div class="alert" id="admin-realm-name-changes-disabled-status"></div>
<div class="alert" id="admin-realm-email-changes-disabled-status"></div>
<div class="alert" id="admin-realm-mandatory-topics-status"></div>
<div class="alert" id="admin-realm-name-changes-disabled-status"></div>
<div class="alert" id="admin-realm-add-emoji-by-admins-only-status"></div>
<div class="alert" id="admin-realm-create-stream-by-admins-only-status"></div>
<div class="alert" id="admin-realm-waiting-period-threshold-status"></div>
<div class="side-padded-container m-10 inline-block organization-permissions-parent">
<div class="input-group admin-restricted-to-domain">
@@ -97,6 +93,15 @@
</label>
</div>
<div class="input-group disableable">
<label for="aitin">{{t "Waiting period for stream creation (in days)" }}</label>
<input type="text" id="id_realm_waiting_period_threshold"
name="realm_waiting_period_threshold"
class="admin-realm-message-content-edit-limit-minutes"
value="{{ realm_waiting_period_threshold }}"/>
</div>
<div class="input-group">
<label class="checkbox">
<input type="checkbox" id="id_realm_add_emoji_by_admins_only" name="realm_add_emoji_by_admins_only"
@@ -110,103 +115,6 @@
</div>
</div>
<h3 class="light">{{t "Message editing" }}</h3>
<div class="side-padded-container m-10 inline-block organization-permissions-parent">
<div class="input-group">
<label class="checkbox">
<input type="checkbox" id="id_realm_allow_message_editing" name="realm_allow_message_editing"
{{#if realm_allow_message_editing}}checked="checked"{{/if}} />
<span></span>
</label>
<label for="id_realm_allow_message_editing" class="inline-block"
title="{{t 'If checked, users can edit the content and topics of their old messages.' }}">
{{t "Users can edit their messages" }}
</label>
</div>
<div class="input-group disableable {{#unless realm_allow_message_editing}}control-label-disabled{{/unless}}">
<label for="id_realm_message_content_edit_limit_minutes"
id="id_realm_message_content_edit_limit_minutes_label"
title="{{t 'If non-zero, users can edit their message for this many minutes after it is sent. If zero, users can edit all their past messages.' }}">
{{t 'Message edit limit in minutes (0 for no limit)' }}
</label>
<input type="text" id="id_realm_message_content_edit_limit_minutes"
name="realm_message_content_edit_limit_minutes"
class="admin-realm-message-content-edit-limit-minutes"
value="{{ realm_message_content_edit_limit_minutes }}"
{{#unless realm_allow_message_editing}}disabled="disabled"{{/unless}} />
</div>
<div class="input-group">
<label class="checkbox">
<input type="checkbox" id="id_realm_allow_edit_history" name="realm_allow_edit_history"
{{#if realm_allow_edit_history}}checked="checked"{{/if}} />
<span></span>
</label>
<label for="id_realm_allow_edit_history" id="id_realm_allow_edit_history_label" class="inline-block"
title="{{t 'If checked, users will be able view message edit history.'}}">
{{t "Enable message edit history" }}
</label>
</div>
</div>
<h3 class="light">{{t "Message feed" }}</h3>
<div class="side-padded-container m-10 inline-block organization-permissions-parent">
{{#if false}}
<div class="input-group">
<label for="realm_message_retention_days"
id="id_realm_message_retention_days_label"
title="{{t 'Messages older than the configured number of days will be automatically deleted' }}">
{{t 'Messages retention period in days (blank means messages are retained forever)' }}
</label>
<input type="text" id="id_realm_message_retention_days"
name="realm_message_retention_days"
class="admin-realm-message-retention-days"
value="{{ realm_message_retention_days }}"/>
</div>
{{/if}}
<div class="input-group">
<label class="checkbox">
<input type="checkbox" id="id_realm_mandatory_topics" name="realm_mandatory_topics"
{{#if realm_mandatory_topics}}checked="checked"{{/if}} />
<span></span>
</label>
<label for="id_realm_mandatory_topics" id="id_realm_mandatory_topics_label" class="inline-block"
title="{{t 'If checked, topics are required.'}}">
{{t "Require topics in stream messages" }}
</label>
</div>
{{#if server_inline_image_preview}}
<div class="input-group">
<label class="checkbox">
<input type="checkbox" id="id_realm_inline_image_preview" name="realm_inline_image_preview"
{{#if realm_inline_image_preview}}checked="checked"{{/if}} />
<span></span>
</label>
<label for="id_realm_inline_image_preview" id="id_realm_inline_image_preview_label" class="inline-block"
title="{{t 'If checked, image previews will be shown.' }}">
{{t "Show previews of uploaded and linked images" }}
</label>
</div>
{{/if}}
{{#if server_inline_url_embed_preview}}
<div class="input-group">
<label class="checkbox">
<input type="checkbox" id="id_realm_inline_url_embed_preview" name="realm_inline_url_embed_preview"
{{#if realm_inline_url_embed_preview}}checked="checked"{{/if}} />
<span></span>
</label>
<label for="id_realm_inline_url_embed_preview" id="id_realm_inline_url_embed_preview_label" class="inline-block"
title="{{t 'If checked, previews of linked websites will be shown.' }}">
{{t "Show previews of linked websites" }}
</label>
</div>
{{/if}}
</div>
{{#if is_admin }}
<div class="input-group organization-submission">
<button type="submit" class="button rounded sea-green">

View File

@@ -0,0 +1,47 @@
<div id="organization-profile" data-name="organization-profile" class="settings-section">
<form class="form-horizontal admin-realm-form org-profile-form">
<h3 class="light">{{t "Organization profile" }}</h3>
<div class="alert" id="admin-realm-name-status"></div>
<div class="alert" id="admin-realm-description-status"></div>
<div class="m-10 inline-block organization-settings-parent">
<div class="input-group admin-realm">
<label for="id_realm_name">{{t "Your organization's name" }}</label>
<input type="text" id="id_realm_name" name="realm_name" class="admin-realm-name"
value="{{ realm_name }}" maxlength="40" />
</div>
<div class="input-group admin-realm">
<label for="realm_description">{{t "Your organization's description" }}</label>
<textarea id="id_realm_description" name="realm_description" class="admin-realm-description"
maxlength="1000">{{ realm_description }}</textarea>
</div>
{{#if is_admin }}
<div class="input-group organization-submission">
<button type="submit" class="button rounded sea-green">
{{t 'Save changes' }}
</button>
</div>
{{/if}}
</div>
<h3 class="light">{{t "Organization avatar" }}</h3>
<div class="realm-icon-section">
<div class="inline-block">
<img id="realm-settings-icon" src="{{ realm_icon_url }}"/>
<div id="realm_icon_file_input_error" class="text-error"></div>
<input type="file" name="realm_icon_file_input" class="notvisible"
id="realm_icon_file_input" value="{{t 'Upload icon' }}"/>
<div id="upload_icon_spinner"></div>
</div>
<div class="inline-block avatar-controls">
<button class="button rounded sea-green w-200 block input-size"
id="realm_icon_upload_button">{{t 'Upload new icon' }}</button>
<button class="button rounded btn-danger w-200 m-t-10 block input-size"
id="realm_icon_delete_button">{{t 'Delete icon' }}</button>
</div>
</div>
</form>
</div>

View File

@@ -1,24 +1,17 @@
<div id="organization-settings" data-name="organization-settings" class="settings-section">
<form class="form-horizontal admin-realm-form org-settings-form">
<h3 class="light">{{t "Organization settings" }}</h3>
<div class="alert" id="admin-realm-name-status"></div>
<div class="alert" id="admin-realm-description-status"></div>
<div class="alert" id="admin-realm-notifications-stream-status"></div>
<div class="alert" id="admin-realm-default-language-status"></div>
<div class="alert" id="admin-realm-waiting-period-threshold-status"></div>
<div class="alert" id="admin-realm-inline-image-preview-status"></div>
<div class="alert" id="admin-realm-inline-url-embed-preview-status"></div>
<div class="alert" id="admin-realm-allow-edit-history-status"></div>
<div class="alert" id="admin-realm-message-editing-status"></div>
<div class="alert" id="admin-realm-mandatory-topics-status"></div>
<h3 class="light">{{t "Language &amp; Notifications" }}</h3>
<div class="m-10 inline-block organization-settings-parent">
<div class="input-group admin-realm">
<label for="id_realm_name">{{t "Your organization's name" }}</label>
<input type="text" id="id_realm_name" name="realm_name" class="admin-realm-name"
value="{{ realm_name }}" maxlength="40" />
</div>
<div class="input-group admin-realm">
<label for="realm_description">{{t "Your organization's description" }}</label>
<textarea id="id_realm_description" name="realm_description" class="admin-realm-description"
maxlength="1000">{{ realm_description }}</textarea>
</div>
<div class="input-group">
<label for="realm_default_language">{{t "Default language" }}:</label>
<select name="realm_default_language" id="id_realm_default_language">
@@ -27,13 +20,6 @@
{{/each}}
</select>
</div>
<div class="input-group">
<label for="id_realm_waiting_period_threshold">{{t "Waiting period for stream creation (in days)" }}</label>
<input type="text" id="id_realm_waiting_period_threshold"
name="realm_waiting_period_threshold"
class="admin-realm-message-content-edit-limit-minutes"
value="{{ realm_waiting_period_threshold }}"/>
</div>
{{#if is_admin }}
<div class="input-group organization-submission">
<button type="submit" class="button rounded sea-green">
@@ -68,22 +54,109 @@
{{/if}}
</div>
<h3 class="light">{{t "Organization avatar" }}</h3>
<h3 class="light">{{t "Message editing" }}</h3>
<div class="side-padded-container m-10 inline-block organization-permissions-parent">
<div class="input-group">
<label class="checkbox">
<input type="checkbox" id="id_realm_allow_message_editing" name="realm_allow_message_editing"
{{#if realm_allow_message_editing}}checked="checked"{{/if}} />
<span></span>
</label>
<label for="id_realm_allow_message_editing" class="inline-block"
title="{{t 'If checked, users can edit the content and topics of their old messages.' }}">
{{t "Users can edit their messages" }}
</label>
</div>
<div class="realm-icon-section">
<div class="inline-block">
<img id="realm-settings-icon" src="{{ realm_icon_url }}"/>
<div id="realm_icon_file_input_error" class="text-error"></div>
<input type="file" name="realm_icon_file_input" class="notvisible"
id="realm_icon_file_input" value="{{t 'Upload icon' }}"/>
<div id="upload_icon_spinner"></div>
<div class="input-group disableable {{#unless realm_allow_message_editing}}control-label-disabled{{/unless}}">
<label for="id_realm_message_content_edit_limit_minutes"
id="id_realm_message_content_edit_limit_minutes_label"
title="{{t 'If non-zero, users can edit their message for this many minutes after it is sent. If zero, users can edit all their past messages.' }}">
{{t 'Message edit limit in minutes (0 for no limit)' }}
</label>
<input type="text" id="id_realm_message_content_edit_limit_minutes"
name="realm_message_content_edit_limit_minutes"
class="admin-realm-message-content-edit-limit-minutes"
value="{{ realm_message_content_edit_limit_minutes }}"
{{#unless realm_allow_message_editing}}disabled="disabled"{{/unless}} />
</div>
<div class="inline-block avatar-controls">
<button class="button rounded sea-green w-200 block input-size"
id="realm_icon_upload_button">{{t 'Upload new icon' }}</button>
<button class="button rounded btn-danger w-200 m-t-10 block input-size"
id="realm_icon_delete_button">{{t 'Delete icon' }}</button>
<div class="input-group">
<label class="checkbox">
<input type="checkbox" id="id_realm_allow_edit_history" name="realm_allow_edit_history"
{{#if realm_allow_edit_history}}checked="checked"{{/if}} />
<span></span>
</label>
<label for="id_realm_allow_edit_history" id="id_realm_allow_edit_history_label" class="inline-block"
title="{{t 'If checked, users will be able view message edit history.'}}">
{{t "Enable message edit history" }}
</label>
</div>
</div>
<h3 class="light">{{t "Message feed" }}</h3>
<div class="side-padded-container m-10 inline-block organization-permissions-parent">
{{#if false}}
<div class="input-group">
<label for="realm_message_retention_days"
id="id_realm_message_retention_days_label"
title="{{t 'Messages older than the configured number of days will be automatically deleted' }}">
{{t 'Messages retention period in days (blank means messages are retained forever)' }}
</label>
<input type="text" id="id_realm_message_retention_days"
name="realm_message_retention_days"
class="admin-realm-message-retention-days"
value="{{ realm_message_retention_days }}"/>
</div>
{{/if}}
<div class="input-group">
<label class="checkbox">
<input type="checkbox" id="id_realm_mandatory_topics" name="realm_mandatory_topics"
{{#if realm_mandatory_topics}}checked="checked"{{/if}} />
<span></span>
</label>
<label for="id_realm_mandatory_topics" id="id_realm_mandatory_topics_label" class="inline-block"
title="{{t 'If checked, topics are required.'}}">
{{t "Require topics in stream messages" }}
</label>
</div>
{{#if server_inline_image_preview}}
<div class="input-group">
<label class="checkbox">
<input type="checkbox" id="id_realm_inline_image_preview" name="realm_inline_image_preview"
{{#if realm_inline_image_preview}}checked="checked"{{/if}} />
<span></span>
</label>
<label for="id_realm_inline_image_preview" id="id_realm_inline_image_preview_label" class="inline-block"
title="{{t 'If checked, image previews will be shown.' }}">
{{t "Show previews of uploaded and linked images" }}
</label>
</div>
{{/if}}
{{#if server_inline_url_embed_preview}}
<div class="input-group">
<label class="checkbox">
<input type="checkbox" id="id_realm_inline_url_embed_preview" name="realm_inline_url_embed_preview"
{{#if realm_inline_url_embed_preview}}checked="checked"{{/if}} />
<span></span>
</label>
<label for="id_realm_inline_url_embed_preview" id="id_realm_inline_url_embed_preview_label" class="inline-block"
title="{{t 'If checked, previews of linked websites will be shown.' }}">
{{t "Show previews of linked websites" }}
</label>
</div>
{{/if}}
</div>
{{#if is_admin }}
<div class="input-group organization-submission">
<button type="submit" class="button rounded sea-green">
{{t 'Save changes' }}
</button>
</div>
{{/if}}
</form>
</div>

View File

@@ -44,6 +44,10 @@
<div class="text">{{ _('Zulip labs') }}</div>
</li>
<li class="admin" tabindex="0" data-section="organization-profile">
<i class="icon icon-vector-lock"></i>
<div class="text">{{ _('Organization profile') }}</div>
</li>
<li class="admin" tabindex="0" data-section="organization-settings">
<i class="icon icon-vector-beaker"></i>
<div class="text">{{ _('Organization settings') }}</div>