mirror of https://github.com/zulip/zulip.git
custom_profile_fields_ui: Convert module to TypeScript.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
e6bfaed782
commit
c9e822f7ad
|
@ -90,7 +90,7 @@ EXEMPT_FILES = make_set(
|
||||||
"web/src/csrf.ts",
|
"web/src/csrf.ts",
|
||||||
"web/src/css_variables.d.ts",
|
"web/src/css_variables.d.ts",
|
||||||
"web/src/css_variables.js",
|
"web/src/css_variables.js",
|
||||||
"web/src/custom_profile_fields_ui.js",
|
"web/src/custom_profile_fields_ui.ts",
|
||||||
"web/src/dark_theme.ts",
|
"web/src/dark_theme.ts",
|
||||||
"web/src/debug.ts",
|
"web/src/debug.ts",
|
||||||
"web/src/demo_organizations_ui.js",
|
"web/src/demo_organizations_ui.js",
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
import flatpickr from "flatpickr";
|
||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
|
import {z} from "zod";
|
||||||
|
|
||||||
import render_settings_custom_user_profile_field from "../templates/settings/custom_user_profile_field.hbs";
|
import render_settings_custom_user_profile_field from "../templates/settings/custom_user_profile_field.hbs";
|
||||||
|
|
||||||
|
@ -7,11 +9,15 @@ import * as bootstrap_typeahead from "./bootstrap_typeahead";
|
||||||
import {$t} from "./i18n";
|
import {$t} from "./i18n";
|
||||||
import * as people from "./people";
|
import * as people from "./people";
|
||||||
import * as pill_typeahead from "./pill_typeahead";
|
import * as pill_typeahead from "./pill_typeahead";
|
||||||
|
import * as settings_components from "./settings_components";
|
||||||
import {realm} from "./state_data";
|
import {realm} from "./state_data";
|
||||||
import * as typeahead_helper from "./typeahead_helper";
|
import * as typeahead_helper from "./typeahead_helper";
|
||||||
|
import type {UserPillWidget} from "./user_pill";
|
||||||
import * as user_pill from "./user_pill";
|
import * as user_pill from "./user_pill";
|
||||||
|
|
||||||
export function append_custom_profile_fields(element_id, user_id) {
|
const user_value_schema = z.array(z.number());
|
||||||
|
|
||||||
|
export function append_custom_profile_fields(element_id: string, user_id: number): void {
|
||||||
const person = people.get_by_user_id(user_id);
|
const person = people.get_by_user_id(user_id);
|
||||||
if (person.is_bot) {
|
if (person.is_bot) {
|
||||||
return;
|
return;
|
||||||
|
@ -39,15 +45,15 @@ export function append_custom_profile_fields(element_id, user_id) {
|
||||||
field_value = {value: "", rendered_value: ""};
|
field_value = {value: "", rendered_value: ""};
|
||||||
}
|
}
|
||||||
if (is_select_field) {
|
if (is_select_field) {
|
||||||
const field_choice_dict = JSON.parse(field.field_data);
|
const field_choice_dict = settings_components.select_field_data_schema.parse(
|
||||||
for (const choice in field_choice_dict) {
|
JSON.parse(field.field_data),
|
||||||
if (choice) {
|
);
|
||||||
field_choices[field_choice_dict[choice].order] = {
|
for (const [value, {order, text}] of Object.entries(field_choice_dict)) {
|
||||||
value: choice,
|
field_choices[Number(order)] = {
|
||||||
text: field_choice_dict[choice].text,
|
value,
|
||||||
selected: choice === field_value.value,
|
text,
|
||||||
};
|
selected: value === field_value.value,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,13 +76,25 @@ export function append_custom_profile_fields(element_id, user_id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initialize_custom_user_type_fields(
|
export function initialize_custom_user_type_fields(
|
||||||
element_id,
|
element_id: string,
|
||||||
user_id,
|
user_id: number,
|
||||||
is_editable,
|
is_editable: boolean,
|
||||||
pill_update_handler,
|
pill_update_handler?: (
|
||||||
) {
|
field: {
|
||||||
|
type: number;
|
||||||
|
field_data: string;
|
||||||
|
hint: string;
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
order: number;
|
||||||
|
required: boolean;
|
||||||
|
display_in_profile_summary?: boolean | undefined;
|
||||||
|
},
|
||||||
|
pills: UserPillWidget,
|
||||||
|
) => void,
|
||||||
|
): Map<number, UserPillWidget> {
|
||||||
const field_types = realm.custom_profile_field_types;
|
const field_types = realm.custom_profile_field_types;
|
||||||
const user_pills = new Map();
|
const user_pills = new Map<number, UserPillWidget>();
|
||||||
|
|
||||||
const person = people.get_by_user_id(user_id);
|
const person = people.get_by_user_id(user_id);
|
||||||
if (person.is_bot) {
|
if (person.is_bot) {
|
||||||
|
@ -84,37 +102,35 @@ export function initialize_custom_user_type_fields(
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const field of realm.custom_profile_fields) {
|
for (const field of realm.custom_profile_fields) {
|
||||||
let field_value_raw = people.get_custom_profile_data(user_id, field.id);
|
const field_value_raw = people.get_custom_profile_data(user_id, field.id)?.value;
|
||||||
|
|
||||||
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
|
// If field is not editable and field value is null, we don't expect
|
||||||
// pill container for that field and proceed further
|
// pill container for that field and proceed further
|
||||||
if (field.type === field_types.USER.id && (field_value_raw || is_editable)) {
|
if (field.type === field_types.USER.id && (field_value_raw !== undefined || is_editable)) {
|
||||||
const $pill_container = $(element_id)
|
const $pill_container = $(element_id)
|
||||||
.find(`.custom_user_field[data-field-id="${CSS.escape(field.id)}"] .pill-container`)
|
.find(
|
||||||
|
`.custom_user_field[data-field-id="${CSS.escape(`${field.id}`)}"] .pill-container`,
|
||||||
|
)
|
||||||
.expectOne();
|
.expectOne();
|
||||||
const pill_config = {
|
const pill_config = {
|
||||||
exclude_inaccessible_users: is_editable,
|
exclude_inaccessible_users: is_editable,
|
||||||
};
|
};
|
||||||
const pills = user_pill.create_pills($pill_container, pill_config);
|
const pills = user_pill.create_pills($pill_container, pill_config);
|
||||||
|
|
||||||
if (field_value_raw) {
|
if (field_value_raw !== undefined) {
|
||||||
const field_value = JSON.parse(field_value_raw);
|
const field_value = user_value_schema.parse(JSON.parse(field_value_raw));
|
||||||
if (field_value) {
|
for (const pill_user_id of field_value) {
|
||||||
for (const pill_user_id of field_value) {
|
const user = people.get_user_by_id_assert_valid(pill_user_id);
|
||||||
const user = people.get_user_by_id_assert_valid(pill_user_id);
|
user_pill.append_user(user, pills);
|
||||||
user_pill.append_user(user, pills);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_editable) {
|
if (is_editable) {
|
||||||
const $input = $pill_container.children(".input");
|
const $input = $pill_container.children(".input");
|
||||||
if (pill_update_handler) {
|
if (pill_update_handler) {
|
||||||
const update_func = () => pill_update_handler(field, pills);
|
const update_func = (): void => {
|
||||||
|
pill_update_handler(field, pills);
|
||||||
|
};
|
||||||
const opts = {
|
const opts = {
|
||||||
update_func,
|
update_func,
|
||||||
exclude_bots: true,
|
exclude_bots: true,
|
||||||
|
@ -134,8 +150,8 @@ export function initialize_custom_user_type_fields(
|
||||||
return user_pills;
|
return user_pills;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initialize_custom_date_type_fields(element_id) {
|
export function initialize_custom_date_type_fields(element_id: string): void {
|
||||||
$(element_id).find(".custom_user_field .datepicker").flatpickr({
|
flatpickr($(element_id).find(".custom_user_field .datepicker")[0]!, {
|
||||||
altInput: true,
|
altInput: true,
|
||||||
altFormat: "F j, Y",
|
altFormat: "F j, Y",
|
||||||
allowInput: true,
|
allowInput: true,
|
||||||
|
@ -143,9 +159,9 @@ export function initialize_custom_date_type_fields(element_id) {
|
||||||
});
|
});
|
||||||
|
|
||||||
$(element_id)
|
$(element_id)
|
||||||
.find(".custom_user_field .datepicker")
|
.find<HTMLInputElement>(".custom_user_field input.datepicker")
|
||||||
.on("mouseenter", function () {
|
.on("mouseenter", function () {
|
||||||
if ($(this).val().length <= 0) {
|
if ($(this).val()!.length <= 0) {
|
||||||
$(this).parent().find(".remove_date").hide();
|
$(this).parent().find(".remove_date").hide();
|
||||||
} else {
|
} else {
|
||||||
$(this).parent().find(".remove_date").show();
|
$(this).parent().find(".remove_date").show();
|
||||||
|
@ -161,15 +177,15 @@ export function initialize_custom_date_type_fields(element_id) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initialize_custom_pronouns_type_fields(element_id) {
|
export function initialize_custom_pronouns_type_fields(element_id: string): void {
|
||||||
const commonly_used_pronouns = [
|
const commonly_used_pronouns = [
|
||||||
$t({defaultMessage: "he/him"}),
|
$t({defaultMessage: "he/him"}),
|
||||||
$t({defaultMessage: "she/her"}),
|
$t({defaultMessage: "she/her"}),
|
||||||
$t({defaultMessage: "they/them"}),
|
$t({defaultMessage: "they/them"}),
|
||||||
];
|
];
|
||||||
const bootstrap_typeahead_input = {
|
const bootstrap_typeahead_input = {
|
||||||
$element: $(element_id).find(".pronouns_type_field"),
|
$element: $(element_id).find<HTMLInputElement>("input.pronouns_type_field"),
|
||||||
type: "input",
|
type: "input" as const,
|
||||||
};
|
};
|
||||||
new Typeahead(bootstrap_typeahead_input, {
|
new Typeahead(bootstrap_typeahead_input, {
|
||||||
items: 3,
|
items: 3,
|
Loading…
Reference in New Issue