retention-period: Add retention period to front-end admin organization settings.

- Add message retention period field to organization settings form.
- Add css for retention period field.
- Add convertor to not negative int or to None.
- Add retention period setting processing to back-end.
- Fix tests.

Modified by tabbott to hide the setting, since it doesn't work yet.
The goal of merging this setting code now is to avoid unnecessary
merge conflicts in the future.

Part of #106.
This commit is contained in:
K.Kanakhin
2016-11-30 15:42:58 +06:00
committed by Tim Abbott
parent 6a884acff5
commit 234a1f8e61
14 changed files with 73 additions and 5 deletions

View File

@@ -374,6 +374,10 @@ exports.populate_auth_methods = function (auth_methods) {
loading.destroy_indicator($('#admin_page_auth_methods_loading_indicator'));
};
exports.update_message_retention_days = function () {
$("#id_realm_message_retention_days").val(page_params.message_retention_days);
};
function _setup_page() {
var options = {
realm_name: page_params.realm_name,
@@ -393,6 +397,7 @@ function _setup_page() {
realm_allow_message_editing: page_params.realm_allow_message_editing,
realm_message_content_edit_limit_minutes:
Math.ceil(page_params.realm_message_content_edit_limit_seconds / 60),
realm_message_retention_days: page_params.realm_message_retention_days,
language_list: page_params.language_list,
realm_default_language: page_params.realm_default_language,
realm_waiting_period_threshold: page_params.realm_waiting_period_threshold,
@@ -669,6 +674,7 @@ function _setup_page() {
var new_add_emoji_by_admins_only = $("#id_realm_add_emoji_by_admins_only").prop("checked");
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_default_language = $("#id_realm_default_language").val();
var new_waiting_period_threshold = $("#id_realm_waiting_period_threshold").val();
var new_auth_methods = {};
@@ -687,6 +693,10 @@ function _setup_page() {
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 = {
@@ -705,6 +715,7 @@ function _setup_page() {
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,
default_language: JSON.stringify(new_default_language),
waiting_period_threshold: JSON.stringify(parseInt(new_waiting_period_threshold, 10)),
};

View File

@@ -81,6 +81,9 @@ function dispatch_normal_event(event) {
page_params.add_emoji_by_admins_only = event.value;
} else if (event.op === 'update' && event.property === 'restricted_to_domain') {
page_params.realm_restricted_to_domain = event.value;
} else if (event.op === 'update' && event.property === 'message_retention_days') {
page_params.message_retention_days = event.value;
admin.update_message_retention_days();
} else if (event.op === 'update_dict' && event.property === 'default') {
$.each(event.data, function (key, value) {
page_params['realm_' + key] = value;

View File

@@ -421,6 +421,11 @@ input[type=checkbox].inline-block {
text-align: right;
}
.admin-realm-message-retention-days {
width: 5ch;
text-align: right;
}
#account-settings-status {
text-align: center;
width: 50%;

View File

@@ -147,6 +147,19 @@
value="{{ realm_message_content_edit_limit_minutes }}"
{{#unless realm_allow_message_editing}}disabled="disabled"{{/unless}} />
</div>
{{#if false}}
<div class="input-group">
<label for="realm_message_retention_days"
id="id_realm_message_retention_days_label"
title="{{t 'If empty, messages are not moved to archive.' }}">
{{t 'Retention period for messages in days (empty for disable)' }}
</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 for="realm_default_language">{{t "Default language" }}:</label>
<select name="realm_default_language" id="id_realm_default_language">

View File

@@ -536,6 +536,14 @@ def to_non_negative_int(s):
raise ValueError("argument is negative")
return x
def to_not_negative_int_or_none(s):
# type: (Text) -> Optional[int]
if s:
return to_non_negative_int(s)
return None
def flexible_boolean(boolean):
# type: (Text) -> bool
"""Returns True for any of "1", "true", or "True". Returns False otherwise."""

View File

@@ -474,7 +474,6 @@ def do_set_realm_message_editing(realm, allow_message_editing, message_content_e
)
send_event(event, active_user_ids(realm))
def do_deactivate_realm(realm):
# type: (Realm) -> None
"""

View File

@@ -104,6 +104,7 @@ def fetch_initial_state_data(user_profile, event_types, queue_id,
state['realm_add_emoji_by_admins_only'] = user_profile.realm.add_emoji_by_admins_only
state['realm_allow_message_editing'] = user_profile.realm.allow_message_editing
state['realm_message_content_edit_limit_seconds'] = user_profile.realm.message_content_edit_limit_seconds
state['realm_message_retention_days'] = user_profile.realm.message_retention_days
state['realm_default_language'] = user_profile.realm.default_language
state['realm_waiting_period_threshold'] = user_profile.realm.waiting_period_threshold
state['realm_icon_url'] = realm_icon_url(user_profile.realm)

View File

@@ -155,6 +155,7 @@ class Realm(ModelReprMixin, models.Model):
invite_by_admins_only=bool,
inline_image_preview=bool,
inline_url_embed_preview=bool,
message_retention_days=int,
name=Text,
name_changes_disabled=bool,
restricted_to_domain=bool,

View File

@@ -72,7 +72,8 @@ from zerver.lib.actions import (
do_add_realm_alias,
do_change_realm_alias,
do_remove_realm_alias,
do_change_icon_source)
do_change_icon_source,
)
from zerver.lib.events import (
apply_events,
fetch_initial_state_data,
@@ -761,6 +762,19 @@ class EventsRegisterTest(ZulipTestCase):
error = schema_checker('events[0]', events[0])
self.assert_on_error(error)
def test_change_message_retention_days(self):
# type: () -> None
schema_checker = check_dict([
('type', equals('realm')),
('op', equals('update')),
('property', equals('message_retention_days')),
('value', check_int),
])
events = self.do_test(
lambda: do_set_realm_property(self.user_profile.realm, "message_retention_days", 30))
error = schema_checker('events[0]', events[0])
self.assert_on_error(error)
def test_change_realm_add_emoji_by_admins_only(self):
# type: () -> None
schema_checker = check_dict([

View File

@@ -110,6 +110,7 @@ class HomeTest(ZulipTestCase):
"realm_invite_by_admins_only",
"realm_invite_required",
"realm_message_content_edit_limit_seconds",
"realm_message_retention_days",
"realm_name",
"realm_name_changes_disabled",
"realm_presence_disabled",

View File

@@ -212,6 +212,13 @@ class RealmTest(ZulipTestCase):
realm = update_with_api(waiting_period_threshold=10)
self.assertEqual(realm.waiting_period_threshold, 10)
# retention_period
set_up_db('message_retention_days', 10)
realm = update_with_api(message_retention_days=20)
self.assertEqual(realm.message_retention_days, 20)
realm = update_with_api(message_retention_days=10)
self.assertEqual(realm.message_retention_days, 10)
def test_admin_restrictions_for_changing_realm_name(self):
# type: () -> None
new_name = 'Mice will play while the cat is away'

0
zerver/tests/tests.py Normal file
View File

View File

@@ -305,6 +305,7 @@ def home_real(request):
'realm_inline_url_embed_preview',
'realm_invite_required',
'realm_message_content_edit_limit_seconds',
'realm_message_retention_days',
'realm_name',
'realm_description',
'realm_name_changes_disabled',

View File

@@ -4,7 +4,7 @@ from typing import Any, Dict, Optional
from django.http import HttpRequest, HttpResponse
from django.utils.translation import ugettext as _
from zerver.decorator import require_realm_admin, to_non_negative_int
from zerver.decorator import require_realm_admin, to_non_negative_int, to_not_negative_int_or_none
from zerver.lib.actions import (
do_set_realm_message_editing,
do_set_realm_authentication_methods,
@@ -34,8 +34,9 @@ def update_realm(request, user_profile, name=REQ(validator=check_string, default
message_content_edit_limit_seconds=REQ(converter=to_non_negative_int, default=None),
default_language=REQ(validator=check_string, default=None),
waiting_period_threshold=REQ(converter=to_non_negative_int, default=None),
authentication_methods=REQ(validator=check_dict([]), default=None)):
# type: (HttpRequest, UserProfile, Optional[str], Optional[str], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[int], Optional[str], Optional[int], Optional[dict]) -> HttpResponse
authentication_methods=REQ(validator=check_dict([]), default=None),
message_retention_days=REQ(converter=to_not_negative_int_or_none, default=None)):
# type: (HttpRequest, UserProfile, Optional[str], Optional[str], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[int], Optional[str], Optional[int], Optional[dict], Optional[int]) -> HttpResponse
# Validation for default_language
if default_language is not None and default_language not in get_available_language_codes():
raise JsonableError(_("Invalid language '%s'" % (default_language,)))
@@ -99,4 +100,7 @@ def update_realm(request, user_profile, name=REQ(validator=check_string, default
if waiting_period_threshold is not None and realm.waiting_period_threshold != waiting_period_threshold:
do_set_realm_property(realm, 'waiting_period_threshold', waiting_period_threshold)
data['waiting_period_threshold'] = waiting_period_threshold
if realm.message_retention_days != message_retention_days:
do_set_realm_property(realm, 'message_retention_days', message_retention_days)
data['message_retention_days'] = message_retention_days
return json_success(data)