mirror of https://github.com/zulip/zulip.git
pill_typeahead: Separate user-only typeahead to specialized function.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
512f4d1476
commit
e6bfaed782
|
@ -56,7 +56,7 @@ function set_up_pill_typeahead({
|
|||
user_group: true,
|
||||
user: true,
|
||||
};
|
||||
pill_typeahead.set_up($pill_container.find(".input"), pill_widget, opts);
|
||||
pill_typeahead.set_up_combined($pill_container.find(".input"), pill_widget, opts);
|
||||
}
|
||||
|
||||
export function create({
|
||||
|
|
|
@ -117,15 +117,14 @@ export function initialize_custom_user_type_fields(
|
|||
const update_func = () => pill_update_handler(field, pills);
|
||||
const opts = {
|
||||
update_func,
|
||||
user: true,
|
||||
exclude_bots: true,
|
||||
};
|
||||
pill_typeahead.set_up($input, pills, opts);
|
||||
pill_typeahead.set_up_user($input, pills, opts);
|
||||
pills.onPillRemove(() => {
|
||||
pill_update_handler(field, pills);
|
||||
});
|
||||
} else {
|
||||
pill_typeahead.set_up($input, pills, {user: true, exclude_bots: true});
|
||||
pill_typeahead.set_up_user($input, pills, {exclude_bots: true});
|
||||
}
|
||||
}
|
||||
user_pills.set(field.id, pills);
|
||||
|
|
|
@ -12,7 +12,7 @@ import type {CombinedPillContainer} from "./typeahead_helper";
|
|||
import * as user_group_pill from "./user_group_pill";
|
||||
import type {UserGroupPillData} from "./user_group_pill";
|
||||
import * as user_pill from "./user_pill";
|
||||
import type {UserPillData} from "./user_pill";
|
||||
import type {UserPillData, UserPillWidget} from "./user_pill";
|
||||
|
||||
function person_matcher(query: string, item: UserPillData): boolean {
|
||||
return (
|
||||
|
@ -27,7 +27,52 @@ function group_matcher(query: string, item: UserGroupPillData): boolean {
|
|||
|
||||
type TypeaheadItem = UserGroupPillData | StreamPillData | UserPillData;
|
||||
|
||||
export function set_up(
|
||||
export function set_up_user(
|
||||
$input: JQuery,
|
||||
pills: UserPillWidget,
|
||||
opts: {
|
||||
exclude_bots?: boolean;
|
||||
update_func?: () => void;
|
||||
},
|
||||
): void {
|
||||
const exclude_bots = opts.exclude_bots;
|
||||
const bootstrap_typeahead_input: TypeaheadInputElement = {
|
||||
$element: $input,
|
||||
type: "contenteditable",
|
||||
};
|
||||
new Typeahead(bootstrap_typeahead_input, {
|
||||
items: 5,
|
||||
dropup: true,
|
||||
source(_query: string): UserPillData[] {
|
||||
return user_pill.typeahead_source(pills, exclude_bots);
|
||||
},
|
||||
highlighter_html(item: UserPillData, _query: string): string {
|
||||
return typeahead_helper.render_person(item);
|
||||
},
|
||||
matcher(item: UserPillData, query: string): boolean {
|
||||
query = query.toLowerCase();
|
||||
query = query.replaceAll("\u00A0", " ");
|
||||
return person_matcher(query, item);
|
||||
},
|
||||
sorter(matches: UserPillData[], query: string): UserPillData[] {
|
||||
const users = matches.filter((match) => people.is_known_user_id(match.user.user_id));
|
||||
return typeahead_helper.sort_recipients({users, query}).map((item) => {
|
||||
assert(item.type === "user");
|
||||
return item;
|
||||
});
|
||||
},
|
||||
updater(item: UserPillData, _query: string): undefined {
|
||||
if (people.is_known_user_id(item.user.user_id)) {
|
||||
user_pill.append_user(item.user, pills);
|
||||
}
|
||||
$input.trigger("focus");
|
||||
opts.update_func?.();
|
||||
},
|
||||
stopAdvance: true,
|
||||
});
|
||||
}
|
||||
|
||||
export function set_up_combined(
|
||||
$input: JQuery,
|
||||
pills: CombinedPillContainer,
|
||||
opts: {
|
||||
|
|
|
@ -132,7 +132,7 @@ export function has_unconverted_data(pill_widget: UserPillWidget): boolean {
|
|||
}
|
||||
|
||||
export function typeahead_source(
|
||||
pill_widget: CombinedPillContainer,
|
||||
pill_widget: UserPillWidget | CombinedPillContainer,
|
||||
exclude_bots?: boolean,
|
||||
): UserPillData[] {
|
||||
const users = exclude_bots ? people.get_realm_active_human_users() : people.get_realm_users();
|
||||
|
@ -148,7 +148,7 @@ export function filter_taken_users(
|
|||
return items;
|
||||
}
|
||||
|
||||
export function append_user(user: User, pills: CombinedPillContainer): void {
|
||||
export function append_user(user: User, pills: UserPillWidget | CombinedPillContainer): void {
|
||||
if (user) {
|
||||
append_person({
|
||||
pill_widget: pills,
|
||||
|
|
|
@ -33,8 +33,9 @@ function override_typeahead_helper(override_rewire) {
|
|||
override_rewire(typeahead_helper, "sort_streams", () => {
|
||||
sort_streams_called = true;
|
||||
});
|
||||
override_rewire(typeahead_helper, "sort_recipients", () => {
|
||||
override_rewire(typeahead_helper, "sort_recipients", ({users}) => {
|
||||
sort_recipients_called = true;
|
||||
return users;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -130,7 +131,100 @@ for (const sub of subs) {
|
|||
stream_data.add_sub(sub);
|
||||
}
|
||||
|
||||
run_test("set_up", ({mock_template, override, override_rewire}) => {
|
||||
run_test("set_up_user", ({mock_template, override, override_rewire}) => {
|
||||
override_rewire(typeahead_helper, "render_person", () => $fake_rendered_person);
|
||||
override_rewire(typeahead_helper, "sort_recipients", ({users}) => {
|
||||
sort_recipients_called = true;
|
||||
return users;
|
||||
});
|
||||
mock_template("input_pill.hbs", true, (data, html) => {
|
||||
assert.equal(typeof data.display_value, "string");
|
||||
assert.equal(typeof data.has_image, "boolean");
|
||||
return html;
|
||||
});
|
||||
let input_pill_typeahead_called = false;
|
||||
const $fake_input = $.create(".input");
|
||||
$fake_input.before = noop;
|
||||
|
||||
const $container = $.create(".pill-container");
|
||||
$container.find = () => $fake_input;
|
||||
|
||||
const $pill_widget = input_pill.create({
|
||||
$container,
|
||||
create_item_from_text: noop,
|
||||
get_text_from_item: noop,
|
||||
});
|
||||
|
||||
let update_func_called = false;
|
||||
function update_func() {
|
||||
update_func_called = true;
|
||||
}
|
||||
|
||||
override(bootstrap_typeahead, "Typeahead", (input_element, config) => {
|
||||
assert.equal(input_element.$element, $fake_input);
|
||||
assert.equal(config.items, 5);
|
||||
assert.ok(config.dropup);
|
||||
assert.ok(config.stopAdvance);
|
||||
|
||||
assert.equal(typeof config.source, "function");
|
||||
assert.equal(typeof config.highlighter_html, "function");
|
||||
assert.equal(typeof config.matcher, "function");
|
||||
assert.equal(typeof config.sorter, "function");
|
||||
assert.equal(typeof config.updater, "function");
|
||||
|
||||
// test queries
|
||||
const person_query = "me";
|
||||
|
||||
(function test_highlighter() {
|
||||
assert.equal(config.highlighter_html(me_item, person_query), $fake_rendered_person);
|
||||
})();
|
||||
|
||||
(function test_matcher() {
|
||||
let result;
|
||||
result = config.matcher(me_item, person_query);
|
||||
assert.ok(result);
|
||||
result = config.matcher(jill_item, person_query);
|
||||
assert.ok(!result);
|
||||
})();
|
||||
|
||||
(function test_sorter() {
|
||||
sort_recipients_called = false;
|
||||
config.sorter([me_item], person_query);
|
||||
assert.ok(sort_recipients_called);
|
||||
})();
|
||||
|
||||
(function test_source() {
|
||||
let expected_result = [];
|
||||
let actual_result = [];
|
||||
const result = config.source(person_query);
|
||||
actual_result = result.map((item) => item.user_id);
|
||||
expected_result = [...expected_result, ...person_items];
|
||||
expected_result = expected_result.map((item) => item.user_id);
|
||||
assert.deepEqual(actual_result, expected_result);
|
||||
})();
|
||||
|
||||
(function test_updater() {
|
||||
function number_of_pills() {
|
||||
const pills = $pill_widget.items();
|
||||
return pills.length;
|
||||
}
|
||||
assert.equal(number_of_pills(), 0);
|
||||
config.updater(me_item, person_query);
|
||||
assert.equal(number_of_pills(), 1);
|
||||
|
||||
assert.ok(update_func_called);
|
||||
})();
|
||||
|
||||
// input_pill_typeahead_called is set true if
|
||||
// no exception occurs in pill_typeahead.set_up_user.
|
||||
input_pill_typeahead_called = true;
|
||||
});
|
||||
|
||||
pill_typeahead.set_up_user($fake_input, $pill_widget, {update_func});
|
||||
assert.ok(input_pill_typeahead_called);
|
||||
});
|
||||
|
||||
run_test("set_up_combined", ({mock_template, override, override_rewire}) => {
|
||||
override_typeahead_helper(override_rewire);
|
||||
mock_template("input_pill.hbs", true, (data, html) => {
|
||||
assert.equal(typeof data.display_value, "string");
|
||||
|
@ -328,12 +422,12 @@ run_test("set_up", ({mock_template, override, override_rewire}) => {
|
|||
})();
|
||||
|
||||
// input_pill_typeahead_called is set true if
|
||||
// no exception occurs in pill_typeahead.set_up.
|
||||
// no exception occurs in pill_typeahead.set_up_combined.
|
||||
input_pill_typeahead_called = true;
|
||||
});
|
||||
|
||||
function test_pill_typeahead(opts) {
|
||||
pill_typeahead.set_up($fake_input, $pill_widget, opts);
|
||||
pill_typeahead.set_up_combined($fake_input, $pill_widget, opts);
|
||||
assert.ok(input_pill_typeahead_called);
|
||||
}
|
||||
|
||||
|
@ -365,6 +459,6 @@ run_test("set_up", ({mock_template, override, override_rewire}) => {
|
|||
opts = {};
|
||||
input_pill_typeahead_called = false;
|
||||
blueslip.expect("error", "Unspecified possible item types");
|
||||
pill_typeahead.set_up($fake_input, $pill_widget, {});
|
||||
pill_typeahead.set_up_combined($fake_input, $pill_widget, {});
|
||||
assert.ok(!input_pill_typeahead_called);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue