2023-09-25 13:16:40 +02:00
|
|
|
import $ from "jquery";
|
|
|
|
|
|
|
|
import render_settings_custom_user_profile_field from "../templates/settings/custom_user_profile_field.hbs";
|
|
|
|
|
2024-05-06 22:31:24 +02:00
|
|
|
import {Typeahead} from "./bootstrap_typeahead";
|
2024-03-13 01:21:10 +01:00
|
|
|
import * as bootstrap_typeahead from "./bootstrap_typeahead";
|
2023-09-25 13:16:40 +02:00
|
|
|
import {$t} from "./i18n";
|
|
|
|
import * as people from "./people";
|
|
|
|
import * as pill_typeahead from "./pill_typeahead";
|
2024-02-13 02:08:24 +01:00
|
|
|
import {realm} from "./state_data";
|
2023-09-25 13:16:40 +02:00
|
|
|
import * as typeahead_helper from "./typeahead_helper";
|
|
|
|
import * as user_pill from "./user_pill";
|
|
|
|
|
|
|
|
export function append_custom_profile_fields(element_id, user_id) {
|
|
|
|
const person = people.get_by_user_id(user_id);
|
|
|
|
if (person.is_bot) {
|
|
|
|
return;
|
|
|
|
}
|
2024-02-13 02:08:24 +01:00
|
|
|
const all_custom_fields = realm.custom_profile_fields;
|
|
|
|
const all_field_types = realm.custom_profile_field_types;
|
2023-09-25 13:16:40 +02:00
|
|
|
|
|
|
|
const all_field_template_types = new Map([
|
|
|
|
[all_field_types.LONG_TEXT.id, "text"],
|
|
|
|
[all_field_types.SHORT_TEXT.id, "text"],
|
|
|
|
[all_field_types.SELECT.id, "select"],
|
|
|
|
[all_field_types.USER.id, "user"],
|
|
|
|
[all_field_types.DATE.id, "date"],
|
|
|
|
[all_field_types.EXTERNAL_ACCOUNT.id, "text"],
|
|
|
|
[all_field_types.URL.id, "url"],
|
|
|
|
[all_field_types.PRONOUNS.id, "text"],
|
|
|
|
]);
|
|
|
|
|
|
|
|
for (const field of all_custom_fields) {
|
|
|
|
let field_value = people.get_custom_profile_data(user_id, field.id);
|
|
|
|
const is_select_field = field.type === all_field_types.SELECT.id;
|
|
|
|
const field_choices = [];
|
|
|
|
|
|
|
|
if (field_value === undefined || field_value === null) {
|
|
|
|
field_value = {value: "", rendered_value: ""};
|
|
|
|
}
|
|
|
|
if (is_select_field) {
|
|
|
|
const field_choice_dict = JSON.parse(field.field_data);
|
|
|
|
for (const choice in field_choice_dict) {
|
|
|
|
if (choice) {
|
|
|
|
field_choices[field_choice_dict[choice].order] = {
|
|
|
|
value: choice,
|
|
|
|
text: field_choice_dict[choice].text,
|
|
|
|
selected: choice === field_value.value,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const html = render_settings_custom_user_profile_field({
|
|
|
|
field,
|
|
|
|
field_type: all_field_template_types.get(field.type),
|
|
|
|
field_value,
|
|
|
|
is_long_text_field: field.type === all_field_types.LONG_TEXT.id,
|
|
|
|
is_user_field: field.type === all_field_types.USER.id,
|
|
|
|
is_date_field: field.type === all_field_types.DATE.id,
|
|
|
|
is_url_field: field.type === all_field_types.URL.id,
|
|
|
|
is_pronouns_field: field.type === all_field_types.PRONOUNS.id,
|
|
|
|
is_select_field,
|
|
|
|
field_choices,
|
|
|
|
for_manage_user_modal: element_id === "#edit-user-form .custom-profile-field-form",
|
2024-03-19 14:22:03 +01:00
|
|
|
is_empty_required_field: field.required && !field_value.value,
|
2023-09-25 13:16:40 +02:00
|
|
|
});
|
2024-04-04 00:18:17 +02:00
|
|
|
$(element_id).append($(html));
|
2023-09-25 13:16:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function initialize_custom_user_type_fields(
|
|
|
|
element_id,
|
|
|
|
user_id,
|
|
|
|
is_editable,
|
|
|
|
pill_update_handler,
|
|
|
|
) {
|
2024-02-13 02:08:24 +01:00
|
|
|
const field_types = realm.custom_profile_field_types;
|
2023-09-25 13:16:40 +02:00
|
|
|
const user_pills = new Map();
|
|
|
|
|
|
|
|
const person = people.get_by_user_id(user_id);
|
|
|
|
if (person.is_bot) {
|
|
|
|
return user_pills;
|
|
|
|
}
|
|
|
|
|
2024-02-13 02:08:24 +01:00
|
|
|
for (const field of realm.custom_profile_fields) {
|
2023-09-25 13:16:40 +02:00
|
|
|
let field_value_raw = people.get_custom_profile_data(user_id, field.id);
|
|
|
|
|
|
|
|
if (field_value_raw) {
|
|
|
|
field_value_raw = field_value_raw.value;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If field is not editable and field value is null, we don't expect
|
|
|
|
// pill container for that field and proceed further
|
|
|
|
if (field.type === field_types.USER.id && (field_value_raw || is_editable)) {
|
|
|
|
const $pill_container = $(element_id)
|
|
|
|
.find(`.custom_user_field[data-field-id="${CSS.escape(field.id)}"] .pill-container`)
|
|
|
|
.expectOne();
|
2024-01-02 15:13:39 +01:00
|
|
|
const pill_config = {
|
|
|
|
exclude_inaccessible_users: is_editable,
|
|
|
|
};
|
|
|
|
const pills = user_pill.create_pills($pill_container, pill_config);
|
2023-09-25 13:16:40 +02:00
|
|
|
|
|
|
|
if (field_value_raw) {
|
|
|
|
const field_value = JSON.parse(field_value_raw);
|
|
|
|
if (field_value) {
|
|
|
|
for (const pill_user_id of field_value) {
|
2023-11-30 16:47:55 +01:00
|
|
|
const user = people.get_user_by_id_assert_valid(pill_user_id);
|
2023-09-25 13:16:40 +02:00
|
|
|
user_pill.append_user(user, pills);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_editable) {
|
|
|
|
const $input = $pill_container.children(".input");
|
|
|
|
if (pill_update_handler) {
|
|
|
|
const update_func = () => pill_update_handler(field, pills);
|
|
|
|
const opts = {
|
|
|
|
update_func,
|
|
|
|
exclude_bots: true,
|
|
|
|
};
|
2024-06-07 00:43:21 +02:00
|
|
|
pill_typeahead.set_up_user($input, pills, opts);
|
2023-09-25 13:16:40 +02:00
|
|
|
pills.onPillRemove(() => {
|
|
|
|
pill_update_handler(field, pills);
|
|
|
|
});
|
|
|
|
} else {
|
2024-06-07 00:43:21 +02:00
|
|
|
pill_typeahead.set_up_user($input, pills, {exclude_bots: true});
|
2023-09-25 13:16:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
user_pills.set(field.id, pills);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return user_pills;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function initialize_custom_date_type_fields(element_id) {
|
|
|
|
$(element_id).find(".custom_user_field .datepicker").flatpickr({
|
|
|
|
altInput: true,
|
|
|
|
altFormat: "F j, Y",
|
|
|
|
allowInput: true,
|
|
|
|
static: true,
|
|
|
|
});
|
|
|
|
|
|
|
|
$(element_id)
|
|
|
|
.find(".custom_user_field .datepicker")
|
|
|
|
.on("mouseenter", function () {
|
|
|
|
if ($(this).val().length <= 0) {
|
|
|
|
$(this).parent().find(".remove_date").hide();
|
|
|
|
} else {
|
|
|
|
$(this).parent().find(".remove_date").show();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
$(element_id)
|
|
|
|
.find(".custom_user_field .remove_date")
|
|
|
|
.on("click", function () {
|
2024-03-07 11:42:17 +01:00
|
|
|
const $custom_user_field = $(this).parent().find(".custom_user_field_value");
|
|
|
|
$custom_user_field.val("");
|
|
|
|
$custom_user_field.trigger("input");
|
2023-09-25 13:16:40 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
export function initialize_custom_pronouns_type_fields(element_id) {
|
|
|
|
const commonly_used_pronouns = [
|
|
|
|
$t({defaultMessage: "he/him"}),
|
|
|
|
$t({defaultMessage: "she/her"}),
|
|
|
|
$t({defaultMessage: "they/them"}),
|
|
|
|
];
|
2024-03-18 06:14:23 +01:00
|
|
|
const bootstrap_typeahead_input = {
|
|
|
|
$element: $(element_id).find(".pronouns_type_field"),
|
|
|
|
type: "input",
|
|
|
|
};
|
2024-05-06 22:31:24 +02:00
|
|
|
new Typeahead(bootstrap_typeahead_input, {
|
2024-03-13 01:21:10 +01:00
|
|
|
items: 3,
|
|
|
|
helpOnEmptyStrings: true,
|
|
|
|
source() {
|
|
|
|
return commonly_used_pronouns;
|
|
|
|
},
|
2024-03-25 04:40:21 +01:00
|
|
|
sorter(items, query) {
|
|
|
|
return bootstrap_typeahead.defaultSorter(items, query);
|
2024-03-18 06:14:23 +01:00
|
|
|
},
|
2024-03-13 01:21:10 +01:00
|
|
|
highlighter_html(item) {
|
|
|
|
return typeahead_helper.render_typeahead_item({primary: item});
|
|
|
|
},
|
|
|
|
});
|
2023-09-25 13:16:40 +02:00
|
|
|
}
|