mirror of https://github.com/zulip/zulip.git
profile: Add hint attribute to custom profile fields.
This is the model for #8876.
This commit is contained in:
parent
00ffa808da
commit
0420b89468
|
@ -4527,8 +4527,10 @@ def notify_realm_custom_profile_fields(realm: Realm, operation: str) -> None:
|
|||
fields=[f.as_dict() for f in fields])
|
||||
send_event(event, active_user_ids(realm.id))
|
||||
|
||||
def try_add_realm_custom_profile_field(realm: Realm, name: Text, field_type: int) -> CustomProfileField:
|
||||
def try_add_realm_custom_profile_field(realm: Realm, name: Text, field_type: int,
|
||||
hint: Text='') -> CustomProfileField:
|
||||
field = CustomProfileField(realm=realm, name=name, field_type=field_type)
|
||||
field.hint = hint
|
||||
field.save()
|
||||
notify_realm_custom_profile_fields(realm, 'add')
|
||||
return field
|
||||
|
@ -4542,9 +4544,10 @@ def do_remove_realm_custom_profile_field(realm: Realm, field: CustomProfileField
|
|||
notify_realm_custom_profile_fields(realm, 'delete')
|
||||
|
||||
def try_update_realm_custom_profile_field(realm: Realm, field: CustomProfileField,
|
||||
name: Text) -> None:
|
||||
name: Text, hint: Text='') -> None:
|
||||
field.name = name
|
||||
field.save(update_fields=['name'])
|
||||
field.hint = hint
|
||||
field.save(update_fields=['name', 'hint'])
|
||||
notify_realm_custom_profile_fields(realm, 'update')
|
||||
|
||||
def do_update_user_custom_profile_data(user_profile: UserProfile,
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.11 on 2018-04-06 04:10
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('zerver', '0155_change_default_realm_description'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='customprofilefield',
|
||||
name='hint',
|
||||
field=models.CharField(default='', max_length=80, null=True),
|
||||
),
|
||||
]
|
|
@ -740,10 +740,10 @@ class UserProfile(AbstractBaseUser, PermissionsMixin):
|
|||
unique_together = (('realm', 'email'),)
|
||||
|
||||
@property
|
||||
def profile_data(self) -> List[Dict[str, Union[int, float, Text]]]:
|
||||
def profile_data(self) -> List[Dict[str, Union[int, float, Optional[Text]]]]:
|
||||
values = CustomProfileFieldValue.objects.filter(user_profile=self)
|
||||
user_data = {v.field_id: v.value for v in values}
|
||||
data = [] # type: List[Dict[str, Union[int, float, Text]]]
|
||||
data = [] # type: List[Dict[str, Union[int, float, Optional[Text]]]]
|
||||
for field in custom_profile_fields_for_realm(self.realm_id):
|
||||
value = user_data.get(field.id, None)
|
||||
field_type = field.field_type
|
||||
|
@ -751,7 +751,7 @@ class UserProfile(AbstractBaseUser, PermissionsMixin):
|
|||
converter = field.FIELD_CONVERTERS[field_type]
|
||||
value = converter(value)
|
||||
|
||||
field_data = {} # type: Dict[str, Union[int, float, Text]]
|
||||
field_data = {} # type: Dict[str, Union[int, float, Optional[Text]]]
|
||||
for k, v in field.as_dict().items():
|
||||
field_data[k] = v
|
||||
field_data['value'] = value
|
||||
|
@ -1873,8 +1873,11 @@ class UserHotspot(models.Model):
|
|||
unique_together = ("user", "hotspot")
|
||||
|
||||
class CustomProfileField(models.Model):
|
||||
HINT_MAX_LENGTH = 80
|
||||
|
||||
realm = models.ForeignKey(Realm, on_delete=CASCADE) # type: Realm
|
||||
name = models.CharField(max_length=100) # type: Text
|
||||
hint = models.CharField(max_length=HINT_MAX_LENGTH, default='', null=True) # type: Optional[Text]
|
||||
|
||||
SHORT_TEXT = 1
|
||||
LONG_TEXT = 2
|
||||
|
@ -1895,11 +1898,12 @@ class CustomProfileField(models.Model):
|
|||
class Meta:
|
||||
unique_together = ('realm', 'name')
|
||||
|
||||
def as_dict(self) -> Dict[str, Union[int, Text]]:
|
||||
def as_dict(self) -> Dict[str, Union[int, Optional[Text]]]:
|
||||
return {
|
||||
'id': self.id,
|
||||
'name': self.name,
|
||||
'type': self.field_type,
|
||||
'hint': self.hint,
|
||||
}
|
||||
|
||||
def __str__(self) -> str:
|
||||
|
|
|
@ -37,6 +37,14 @@ class CustomProfileFieldTest(ZulipTestCase):
|
|||
self.assert_json_error(result, u'Invalid field type.')
|
||||
|
||||
data["name"] = "Phone"
|
||||
data["hint"] = "*" * 81
|
||||
data["field_type"] = CustomProfileField.SHORT_TEXT
|
||||
result = self.client_post("/json/realm/profile_fields", info=data)
|
||||
msg = "hint is longer than 80."
|
||||
self.assert_json_error(result, msg)
|
||||
|
||||
data["name"] = "Phone"
|
||||
data["hint"] = "Contact number"
|
||||
data["field_type"] = CustomProfileField.SHORT_TEXT
|
||||
result = self.client_post("/json/realm/profile_fields", info=data)
|
||||
self.assert_json_success(result)
|
||||
|
@ -90,10 +98,31 @@ class CustomProfileFieldTest(ZulipTestCase):
|
|||
info={'name': 'New phone number',
|
||||
'field_type': CustomProfileField.SHORT_TEXT})
|
||||
self.assert_json_success(result)
|
||||
field = CustomProfileField.objects.get(id=field.id, realm=realm)
|
||||
self.assertEqual(CustomProfileField.objects.count(), 3)
|
||||
self.assertEqual(field.name, 'New phone number')
|
||||
self.assertIs(field.hint, '')
|
||||
self.assertEqual(field.field_type, CustomProfileField.SHORT_TEXT)
|
||||
|
||||
result = self.client_patch(
|
||||
"/json/realm/profile_fields/{}".format(field.id),
|
||||
info={'name': 'New phone number',
|
||||
'hint': '*' * 81,
|
||||
'field_type': CustomProfileField.SHORT_TEXT})
|
||||
msg = "hint is longer than 80."
|
||||
self.assert_json_error(result, msg)
|
||||
|
||||
result = self.client_patch(
|
||||
"/json/realm/profile_fields/{}".format(field.id),
|
||||
info={'name': 'New phone number',
|
||||
'hint': 'New contact number',
|
||||
'field_type': CustomProfileField.SHORT_TEXT})
|
||||
self.assert_json_success(result)
|
||||
|
||||
field = CustomProfileField.objects.get(id=field.id, realm=realm)
|
||||
self.assertEqual(CustomProfileField.objects.count(), 3)
|
||||
self.assertEqual(field.name, 'New phone number')
|
||||
self.assertEqual(field.hint, 'New contact number')
|
||||
self.assertEqual(field.field_type, CustomProfileField.SHORT_TEXT)
|
||||
|
||||
def test_update_is_aware_of_uniqueness(self) -> None:
|
||||
|
|
|
@ -18,6 +18,7 @@ from zerver.models import (
|
|||
)
|
||||
|
||||
from zerver.lib.actions import (
|
||||
try_update_realm_custom_profile_field,
|
||||
bulk_add_subscriptions,
|
||||
bulk_remove_subscriptions,
|
||||
check_add_realm_emoji,
|
||||
|
@ -915,6 +916,7 @@ class EventsRegisterTest(ZulipTestCase):
|
|||
('id', check_int),
|
||||
('type', check_int),
|
||||
('name', check_string),
|
||||
('hint', check_string),
|
||||
]))),
|
||||
])
|
||||
|
||||
|
@ -926,6 +928,20 @@ class EventsRegisterTest(ZulipTestCase):
|
|||
error = schema_checker('events[0]', events[0])
|
||||
self.assert_on_error(error)
|
||||
|
||||
realm = self.user_profile.realm
|
||||
field = realm.customprofilefield_set.get(realm=realm, name='Biography')
|
||||
name = field.name
|
||||
hint = 'Biography of the user'
|
||||
try_update_realm_custom_profile_field(realm, field, name, hint=hint)
|
||||
|
||||
events = self.do_test(
|
||||
lambda: notify_realm_custom_profile_fields(
|
||||
self.user_profile.realm, 'add'),
|
||||
state_change_expected=False,
|
||||
)
|
||||
error = schema_checker('events[0]', events[0])
|
||||
self.assert_on_error(error)
|
||||
|
||||
def test_presence_events(self) -> None:
|
||||
schema_checker = self.check_events_dict([
|
||||
('type', equals('presence')),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
from typing import Text, Union, List, Dict
|
||||
from typing import Text, Union, List, Dict, Optional
|
||||
import logging
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
|
@ -14,7 +14,7 @@ from zerver.lib.actions import (try_add_realm_custom_profile_field,
|
|||
try_update_realm_custom_profile_field,
|
||||
do_update_user_custom_profile_data)
|
||||
from zerver.lib.response import json_success, json_error
|
||||
from zerver.lib.validator import check_dict, check_list, check_int
|
||||
from zerver.lib.validator import check_dict, check_list, check_int, check_capped_string
|
||||
|
||||
from zerver.models import (custom_profile_fields_for_realm, UserProfile,
|
||||
CustomProfileField, custom_profile_fields_for_realm)
|
||||
|
@ -23,14 +23,21 @@ def list_realm_custom_profile_fields(request: HttpRequest, user_profile: UserPro
|
|||
fields = custom_profile_fields_for_realm(user_profile.realm_id)
|
||||
return json_success({'custom_fields': [f.as_dict() for f in fields]})
|
||||
|
||||
hint_validator = check_capped_string(CustomProfileField.HINT_MAX_LENGTH)
|
||||
|
||||
@require_realm_admin
|
||||
@has_request_variables
|
||||
def create_realm_custom_profile_field(request: HttpRequest,
|
||||
user_profile: UserProfile, name: Text=REQ(),
|
||||
hint: Text=REQ(default=''),
|
||||
field_type: int=REQ(validator=check_int)) -> HttpResponse:
|
||||
if not name.strip():
|
||||
return json_error(_("Name cannot be blank."))
|
||||
|
||||
error = hint_validator('hint', hint)
|
||||
if error:
|
||||
return json_error(error)
|
||||
|
||||
if field_type not in CustomProfileField.FIELD_VALIDATORS:
|
||||
return json_error(_("Invalid field type."))
|
||||
|
||||
|
@ -39,6 +46,7 @@ def create_realm_custom_profile_field(request: HttpRequest,
|
|||
realm=user_profile.realm,
|
||||
name=name,
|
||||
field_type=field_type,
|
||||
hint=hint,
|
||||
)
|
||||
return json_success({'id': field.id})
|
||||
except IntegrityError:
|
||||
|
@ -59,10 +67,16 @@ def delete_realm_custom_profile_field(request: HttpRequest, user_profile: UserPr
|
|||
@require_realm_admin
|
||||
@has_request_variables
|
||||
def update_realm_custom_profile_field(request: HttpRequest, user_profile: UserProfile,
|
||||
field_id: int, name: Text=REQ()) -> HttpResponse:
|
||||
field_id: int, name: Text=REQ(),
|
||||
hint: Text=REQ(default='')
|
||||
) -> HttpResponse:
|
||||
if not name.strip():
|
||||
return json_error(_("Name cannot be blank."))
|
||||
|
||||
error = hint_validator('hint', hint)
|
||||
if error:
|
||||
return json_error(error, data={'field': 'hint'})
|
||||
|
||||
realm = user_profile.realm
|
||||
try:
|
||||
field = CustomProfileField.objects.get(realm=realm, id=field_id)
|
||||
|
@ -70,7 +84,7 @@ def update_realm_custom_profile_field(request: HttpRequest, user_profile: UserPr
|
|||
return json_error(_('Field id {id} not found.').format(id=field_id))
|
||||
|
||||
try:
|
||||
try_update_realm_custom_profile_field(realm, field, name)
|
||||
try_update_realm_custom_profile_field(realm, field, name, hint=hint)
|
||||
except IntegrityError:
|
||||
return json_error(_('A field with that name already exists.'))
|
||||
return json_success()
|
||||
|
|
|
@ -253,11 +253,14 @@ class Command(BaseCommand):
|
|||
|
||||
# Create custom profile field data
|
||||
phone_number = try_add_realm_custom_profile_field(zulip_realm, "Phone number",
|
||||
CustomProfileField.SHORT_TEXT)
|
||||
CustomProfileField.SHORT_TEXT,
|
||||
hint='')
|
||||
biography = try_add_realm_custom_profile_field(zulip_realm, "Biography",
|
||||
CustomProfileField.LONG_TEXT)
|
||||
CustomProfileField.LONG_TEXT,
|
||||
hint='What are you known for?')
|
||||
favorite_food = try_add_realm_custom_profile_field(zulip_realm, "Favorite food",
|
||||
CustomProfileField.SHORT_TEXT)
|
||||
CustomProfileField.SHORT_TEXT,
|
||||
hint="Or drink, if you'd prefer")
|
||||
|
||||
# Fill in values for Iago and Hamlet
|
||||
hamlet = get_user("hamlet@zulip.com", zulip_realm)
|
||||
|
|
Loading…
Reference in New Issue