mirror of https://github.com/zulip/zulip.git
custom profile fields: Markdown rendering for custom profile field values.
This makes it possible it include our standard markdown formatting in one's custom profile fields, allowing for links, emphasis, emoji, etc. Fixes #10131.
This commit is contained in:
parent
28d344b4b5
commit
e3aed0f7bc
|
@ -240,11 +240,12 @@ initialize();
|
||||||
run_test('set_custom_profile_field_data', () => {
|
run_test('set_custom_profile_field_data', () => {
|
||||||
var person = people.get_by_email(me.email);
|
var person = people.get_by_email(me.email);
|
||||||
me.profile_data = {};
|
me.profile_data = {};
|
||||||
var field = {id: 3, name: 'Custom long field', type: 'text', value: 'Field value'};
|
var field = {id: 3, name: 'Custom long field', type: 'text', value: 'Field value', rendered_value: '<p>Field value</p>'};
|
||||||
people.set_custom_profile_field_data(person.user_id, {});
|
people.set_custom_profile_field_data(person.user_id, {});
|
||||||
assert.deepEqual(person.profile_data, {});
|
assert.deepEqual(person.profile_data, {});
|
||||||
people.set_custom_profile_field_data(person.user_id, field);
|
people.set_custom_profile_field_data(person.user_id, field);
|
||||||
assert.equal(person.profile_data[field.id].value, 'Field value');
|
assert.equal(person.profile_data[field.id].value, 'Field value');
|
||||||
|
assert.equal(person.profile_data[field.id].rendered_value, '<p>Field value</p>');
|
||||||
});
|
});
|
||||||
|
|
||||||
run_test('get_rest_of_realm', () => {
|
run_test('get_rest_of_realm', () => {
|
||||||
|
|
|
@ -591,7 +591,7 @@ run_test('compose_private_stream_alert', () => {
|
||||||
|
|
||||||
run_test('custom_user_profile_field', () => {
|
run_test('custom_user_profile_field', () => {
|
||||||
var field = {name: "GitHub user name", id: 2, hint: "Or link to profile"};
|
var field = {name: "GitHub user name", id: 2, hint: "Or link to profile"};
|
||||||
var args = {field: field, field_value: {value: "@GitHub"}, field_type: "text"};
|
var args = {field: field, field_value: {value: "@GitHub", rendered_value: "<p>@GitHub</p>"}, field_type: "text"};
|
||||||
var html = render('custom-user-profile-field', args);
|
var html = render('custom-user-profile-field', args);
|
||||||
assert.equal($(html).attr('data-field-id'), 2);
|
assert.equal($(html).attr('data-field-id'), 2);
|
||||||
assert.equal($(html).find('.custom_user_field_value').val(), "@GitHub");
|
assert.equal($(html).find('.custom_user_field_value').val(), "@GitHub");
|
||||||
|
|
|
@ -157,9 +157,10 @@ run_test('updates', () => {
|
||||||
blueslip.clear_test_data();
|
blueslip.clear_test_data();
|
||||||
|
|
||||||
me.profile_data = {};
|
me.profile_data = {};
|
||||||
user_events.update_person({user_id: me.user_id, custom_profile_field: {id: 3, value: 'Value'}});
|
user_events.update_person({user_id: me.user_id, custom_profile_field: {id: 3, value: 'Value', rendered_value: '<p>Value</p>'}});
|
||||||
person = people.get_by_email(me.email);
|
person = people.get_by_email(me.email);
|
||||||
assert.equal(person.profile_data[3].value, 'Value');
|
assert.equal(person.profile_data[3].value, 'Value');
|
||||||
|
assert.equal(person.profile_data[3].rendered_value, '<p>Value</p>');
|
||||||
|
|
||||||
var updated = false;
|
var updated = false;
|
||||||
settings_account.update_email = (email) => {
|
settings_account.update_email = (email) => {
|
||||||
|
|
|
@ -983,6 +983,7 @@ exports.set_custom_profile_field_data = function (user_id, field) {
|
||||||
}
|
}
|
||||||
people_by_user_id_dict.get(user_id).profile_data[field.id] = {
|
people_by_user_id_dict.get(user_id).profile_data[field.id] = {
|
||||||
value: field.value,
|
value: field.value,
|
||||||
|
rendered_value: field.rendered_value,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -256,9 +256,13 @@ exports.show_user_profile = function (user) {
|
||||||
var field_choice_dict = JSON.parse(field.field_data);
|
var field_choice_dict = JSON.parse(field.field_data);
|
||||||
profile_field.value = field_choice_dict[field_value.value].text;
|
profile_field.value = field_choice_dict[field_value.value].text;
|
||||||
break;
|
break;
|
||||||
|
case field_types.SHORT_TEXT.id:
|
||||||
|
case field_types.LONG_TEXT.id:
|
||||||
|
profile_field.value = field_value.value;
|
||||||
|
profile_field.rendered_value = field_value.rendered_value;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
profile_field.value = field_value.value;
|
profile_field.value = field_value.value;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
profile_data.push(profile_field);
|
profile_data.push(profile_field);
|
||||||
});
|
});
|
||||||
|
|
|
@ -164,6 +164,7 @@ exports.intialize_custom_user_type_fields = function (element_id, user_id, is_ed
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_editable) {
|
if (is_editable) {
|
||||||
var input = pill_container.children('.input');
|
var input = pill_container.children('.input');
|
||||||
if (set_handler_on_update) {
|
if (set_handler_on_update) {
|
||||||
|
|
|
@ -44,13 +44,17 @@
|
||||||
<div data-type="{{this.type}}" class="field-section custom_user_field" data-field-id="{{this.id}}">
|
<div data-type="{{this.type}}" class="field-section custom_user_field" data-field-id="{{this.id}}">
|
||||||
<div class="name">{{this.name}}</div>
|
<div class="name">{{this.name}}</div>
|
||||||
{{#if this.is_user_field}}
|
{{#if this.is_user_field}}
|
||||||
<div class="pill-container not-editable" data-field-id="{{this.id}}">
|
<div class="pill-container not-editable" data-field-id="{{this.id}}">
|
||||||
<div class="input" contenteditable="false" style="display: none;"></div>
|
<div class="input" contenteditable="false" style="display: none;"></div>
|
||||||
</div>
|
</div>
|
||||||
{{else if this.is_link}}
|
{{else if this.is_link}}
|
||||||
<a href={{this.value}} target="_blank" class="value">{{this.value}}</a>
|
<a href={{this.value}} target="_blank" class="value">{{this.value}}</a>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="value">{{this.value}}</div>
|
{{#if this.rendered_value}}
|
||||||
|
<div class="value">{{{this.rendered_value}}}</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="value">{{this.value}}</div>
|
||||||
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
|
@ -63,9 +63,15 @@ def get_raw_user_data(realm_id: int, client_gravatar: bool) -> Dict[int, Dict[st
|
||||||
profiles_by_user_id = defaultdict(dict) # type: Dict[int, Dict[str, Any]]
|
profiles_by_user_id = defaultdict(dict) # type: Dict[int, Dict[str, Any]]
|
||||||
for profile_field in custom_profile_field_values:
|
for profile_field in custom_profile_field_values:
|
||||||
user_id = profile_field.user_profile_id
|
user_id = profile_field.user_profile_id
|
||||||
profiles_by_user_id[user_id][profile_field.field_id] = {
|
if profile_field.field.is_renderable():
|
||||||
"value": profile_field.value
|
profiles_by_user_id[user_id][profile_field.field_id] = {
|
||||||
}
|
"value": profile_field.value,
|
||||||
|
"rendered_value": profile_field.rendered_value
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
profiles_by_user_id[user_id][profile_field.field_id] = {
|
||||||
|
"value": profile_field.value
|
||||||
|
}
|
||||||
|
|
||||||
def user_data(row: Dict[str, Any]) -> Dict[str, Any]:
|
def user_data(row: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
avatar_url = get_avatar_field(
|
avatar_url = get_avatar_field(
|
||||||
|
@ -407,9 +413,15 @@ def apply_event(state: Dict[str, Any],
|
||||||
if 'custom_profile_field' in person:
|
if 'custom_profile_field' in person:
|
||||||
custom_field_id = person['custom_profile_field']['id']
|
custom_field_id = person['custom_profile_field']['id']
|
||||||
custom_field_new_value = person['custom_profile_field']['value']
|
custom_field_new_value = person['custom_profile_field']['value']
|
||||||
p['profile_data'][custom_field_id] = {
|
if 'rendered_value' in person['custom_profile_field']:
|
||||||
'value': custom_field_new_value
|
p['profile_data'][custom_field_id] = {
|
||||||
}
|
'value': custom_field_new_value,
|
||||||
|
'rendered_value': person['custom_profile_field']['rendered_value']
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
p['profile_data'][custom_field_id] = {
|
||||||
|
'value': custom_field_new_value
|
||||||
|
}
|
||||||
|
|
||||||
elif event['type'] == 'realm_bot':
|
elif event['type'] == 'realm_bot':
|
||||||
if event['op'] == 'add':
|
if event['op'] == 'add':
|
||||||
|
|
|
@ -1067,7 +1067,7 @@ class EventsRegisterTest(ZulipTestCase):
|
||||||
self.assert_on_error(error)
|
self.assert_on_error(error)
|
||||||
|
|
||||||
def test_custom_profile_field_data_events(self) -> None:
|
def test_custom_profile_field_data_events(self) -> None:
|
||||||
schema_checker = self.check_events_dict([
|
schema_checker_basic = self.check_events_dict([
|
||||||
('type', equals('realm_user')),
|
('type', equals('realm_user')),
|
||||||
('op', equals('update')),
|
('op', equals('update')),
|
||||||
('person', check_dict_only([
|
('person', check_dict_only([
|
||||||
|
@ -1079,6 +1079,19 @@ class EventsRegisterTest(ZulipTestCase):
|
||||||
])),
|
])),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
schema_checker_with_rendered_value = self.check_events_dict([
|
||||||
|
('type', equals('realm_user')),
|
||||||
|
('op', equals('update')),
|
||||||
|
('person', check_dict_only([
|
||||||
|
('user_id', check_int),
|
||||||
|
('custom_profile_field', check_dict([
|
||||||
|
('id', check_int),
|
||||||
|
('value', check_none_or(check_string)),
|
||||||
|
('rendered_value', check_none_or(check_string)),
|
||||||
|
], _allow_only_listed_keys=False)),
|
||||||
|
])),
|
||||||
|
])
|
||||||
|
|
||||||
realm = get_realm("zulip")
|
realm = get_realm("zulip")
|
||||||
field_id = realm.customprofilefield_set.get(realm=realm, name='Biography').id
|
field_id = realm.customprofilefield_set.get(realm=realm, name='Biography').id
|
||||||
field = {
|
field = {
|
||||||
|
@ -1086,7 +1099,7 @@ class EventsRegisterTest(ZulipTestCase):
|
||||||
"value": "New value",
|
"value": "New value",
|
||||||
}
|
}
|
||||||
events = self.do_test(lambda: do_update_user_custom_profile_data(self.user_profile, [field]))
|
events = self.do_test(lambda: do_update_user_custom_profile_data(self.user_profile, [field]))
|
||||||
error = schema_checker('events[0]', events[0])
|
error = schema_checker_with_rendered_value('events[0]', events[0])
|
||||||
self.assert_on_error(error)
|
self.assert_on_error(error)
|
||||||
|
|
||||||
# Test we pass correct stringify value in custom-user-field data event
|
# Test we pass correct stringify value in custom-user-field data event
|
||||||
|
@ -1096,7 +1109,7 @@ class EventsRegisterTest(ZulipTestCase):
|
||||||
"value": [self.example_user("ZOE").id],
|
"value": [self.example_user("ZOE").id],
|
||||||
}
|
}
|
||||||
events = self.do_test(lambda: do_update_user_custom_profile_data(self.user_profile, [field]))
|
events = self.do_test(lambda: do_update_user_custom_profile_data(self.user_profile, [field]))
|
||||||
error = schema_checker('events[0]', events[0])
|
error = schema_checker_basic('events[0]', events[0])
|
||||||
self.assert_on_error(error)
|
self.assert_on_error(error)
|
||||||
|
|
||||||
def test_presence_events(self) -> None:
|
def test_presence_events(self) -> None:
|
||||||
|
|
Loading…
Reference in New Issue