mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 14:03:30 +00:00
list_render: Clean up initialization.
For some widgets we now avoid duplicate redraw
events from this old pattern:
widget = list_render.create(..., {
}).init();
widget.sort(...);
The above code was wasteful and possibly
flicker-y due to the fact that `init` and
`sort` both render.
Now we do this:
widget = list_render.create(..., {
init_sort: [...],
});
For other widgets we just clean up the need
to call `init()` right after `create()`.
We also allow widgets to pass in `sort_fields`
during initialization (since you may want to
have `init_sort` use a custom sort before the
first render.)
This commit is contained in:
@@ -106,8 +106,7 @@ run_test('scrolling', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
container.html = (html) => { assert.equal(html, ''); };
|
container.html = (html) => { assert.equal(html, ''); };
|
||||||
const widget = list_render.create(container, items, opts);
|
list_render.create(container, items, opts);
|
||||||
widget.init();
|
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
container.appended_data.html(),
|
container.appended_data.html(),
|
||||||
@@ -154,7 +153,6 @@ run_test('filtering', () => {
|
|||||||
|
|
||||||
container.html = (html) => { assert.equal(html, ''); };
|
container.html = (html) => { assert.equal(html, ''); };
|
||||||
let widget = list_render.create(container, list, opts);
|
let widget = list_render.create(container, list, opts);
|
||||||
widget.init();
|
|
||||||
|
|
||||||
let expected_html =
|
let expected_html =
|
||||||
'<div>apple</div>' +
|
'<div>apple</div>' +
|
||||||
@@ -186,7 +184,7 @@ run_test('filtering', () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
widget.data(new_data);
|
widget.data(new_data);
|
||||||
widget.init();
|
widget.redraw();
|
||||||
expected_html =
|
expected_html =
|
||||||
'<div>greta</div>' +
|
'<div>greta</div>' +
|
||||||
'<div>gary</div>' +
|
'<div>gary</div>' +
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ function render_attachments_ui() {
|
|||||||
const uploaded_files_table = $("#uploaded_files_table").expectOne();
|
const uploaded_files_table = $("#uploaded_files_table").expectOne();
|
||||||
const $search_input = $("#upload_file_search");
|
const $search_input = $("#upload_file_search");
|
||||||
|
|
||||||
const list = list_render.create(uploaded_files_table, attachments, {
|
list_render.create(uploaded_files_table, attachments, {
|
||||||
name: "uploaded-files-list",
|
name: "uploaded-files-list",
|
||||||
modifier: function (attachment) {
|
modifier: function (attachment) {
|
||||||
return render_uploaded_files_list({ attachment: attachment });
|
return render_uploaded_files_list({ attachment: attachment });
|
||||||
@@ -92,11 +92,12 @@ function render_attachments_ui() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
parent_container: $('#attachments-settings').expectOne(),
|
parent_container: $('#attachments-settings').expectOne(),
|
||||||
}).init();
|
init_sort: ['numeric', 'create_time'],
|
||||||
|
sort_fields: {
|
||||||
|
mentioned_in: sort_mentioned_in,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
list.sort('numeric', 'create_time');
|
|
||||||
|
|
||||||
list.add_sort_function("mentioned_in", sort_mentioned_in);
|
|
||||||
ui.reset_scrollbar(uploaded_files_table.closest(".progressive-table-wrapper"));
|
ui.reset_scrollbar(uploaded_files_table.closest(".progressive-table-wrapper"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,15 +50,12 @@ exports.create = function ($container, list, opts) {
|
|||||||
// this memoizes the results and will return a previously invoked
|
// this memoizes the results and will return a previously invoked
|
||||||
// instance
|
// instance
|
||||||
if (opts.name && DEFAULTS.instances.get(opts.name)) {
|
if (opts.name && DEFAULTS.instances.get(opts.name)) {
|
||||||
// the false flag here means "don't run `init`". This is because a
|
const old_widget = DEFAULTS.instances.get(opts.name);
|
||||||
// user is likely reinitializing and will have put .init() afterwards.
|
|
||||||
// This happens when the same codepath is hit multiple times.
|
old_widget.data(list);
|
||||||
return DEFAULTS.instances.get(opts.name)
|
old_widget.redraw();
|
||||||
.set_container($container)
|
|
||||||
.set_opts(opts)
|
return old_widget;
|
||||||
.set_up_event_handlers()
|
|
||||||
.data(list)
|
|
||||||
.init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const meta = {
|
const meta = {
|
||||||
@@ -129,17 +126,14 @@ exports.create = function ($container, list, opts) {
|
|||||||
|
|
||||||
$container.append($(html));
|
$container.append($(html));
|
||||||
meta.offset += load_count;
|
meta.offset += load_count;
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fills the container with an initial batch of items.
|
// Fills the container with an initial batch of items.
|
||||||
// Needs to be enough to exceed the max height, so that a
|
// Needs to be enough to exceed the max height, so that a
|
||||||
// scrollable area is created.
|
// scrollable area is created.
|
||||||
widget.init = function () {
|
widget.redraw = function () {
|
||||||
this.clear();
|
widget.clear();
|
||||||
this.render(DEFAULTS.INITIAL_RENDER_COUNT);
|
widget.render(DEFAULTS.INITIAL_RENDER_COUNT);
|
||||||
return this;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
widget.filter = function (map_function) {
|
widget.filter = function (map_function) {
|
||||||
@@ -169,40 +163,21 @@ exports.create = function ($container, list, opts) {
|
|||||||
|
|
||||||
widget.clear();
|
widget.clear();
|
||||||
|
|
||||||
return this;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
blueslip.warn("The data object provided to the progressive" +
|
blueslip.warn("The data object provided to the progressive" +
|
||||||
" list render is invalid");
|
" list render is invalid");
|
||||||
return this;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
widget.clear = function () {
|
widget.clear = function () {
|
||||||
$container.html("");
|
$container.html("");
|
||||||
meta.offset = 0;
|
meta.offset = 0;
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
widget.set_container = function ($new_container) {
|
|
||||||
if ($new_container) {
|
|
||||||
$container = $new_container;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
widget.set_opts = function (new_opts) {
|
|
||||||
if (opts) {
|
|
||||||
opts = new_opts;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
widget.reverse = function () {
|
widget.reverse = function () {
|
||||||
meta.filtered_list.reverse();
|
meta.filtered_list.reverse();
|
||||||
widget.init();
|
widget.redraw();
|
||||||
return this;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// the sorting function is either the function or string that calls the
|
// the sorting function is either the function or string that calls the
|
||||||
@@ -237,7 +212,7 @@ exports.create = function ($container, list, opts) {
|
|||||||
if (!do_not_display) {
|
if (!do_not_display) {
|
||||||
// clear and re-initialize the list with the newly filtered subset
|
// clear and re-initialize the list with the newly filtered subset
|
||||||
// of items.
|
// of items.
|
||||||
widget.init();
|
widget.redraw();
|
||||||
|
|
||||||
if (opts.filter && opts.filter.onupdate) {
|
if (opts.filter && opts.filter.onupdate) {
|
||||||
opts.filter.onupdate();
|
opts.filter.onupdate();
|
||||||
@@ -245,10 +220,6 @@ exports.create = function ($container, list, opts) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
widget.add_sort_function = function (name, sorting_function) {
|
|
||||||
meta.sorting_functions.set(name, sorting_function);
|
|
||||||
};
|
|
||||||
|
|
||||||
// generic sorting functions are ones that will use a specified prop
|
// generic sorting functions are ones that will use a specified prop
|
||||||
// and perform a sort on it with the given sorting function.
|
// and perform a sort on it with the given sorting function.
|
||||||
widget.add_generic_sort_function = function (name, sorting_function) {
|
widget.add_generic_sort_function = function (name, sorting_function) {
|
||||||
@@ -296,21 +267,19 @@ exports.create = function ($container, list, opts) {
|
|||||||
// from the last sort.
|
// from the last sort.
|
||||||
// it will then also not run an update in the DOM (because we
|
// it will then also not run an update in the DOM (because we
|
||||||
// pass `true`), because it will update regardless below at
|
// pass `true`), because it will update regardless below at
|
||||||
// `widget.init()`.
|
// `widget.redraw()`.
|
||||||
widget.sort(undefined, meta.prop, true);
|
widget.sort(undefined, meta.prop, true);
|
||||||
filter_list(value);
|
filter_list(value);
|
||||||
|
|
||||||
// clear and re-initialize the list with the newly filtered subset
|
// clear and re-initialize the list with the newly filtered subset
|
||||||
// of items.
|
// of items.
|
||||||
widget.init();
|
widget.redraw();
|
||||||
|
|
||||||
if (opts.filter.onupdate) {
|
if (opts.filter.onupdate) {
|
||||||
opts.filter.onupdate();
|
opts.filter.onupdate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// add built-in generic sort functions.
|
// add built-in generic sort functions.
|
||||||
@@ -344,6 +313,18 @@ exports.create = function ($container, list, opts) {
|
|||||||
|
|
||||||
widget.set_up_event_handlers();
|
widget.set_up_event_handlers();
|
||||||
|
|
||||||
|
if (opts.sort_fields) {
|
||||||
|
for (const [name, sorting_function] of Object.entries(opts.sort_fields)) {
|
||||||
|
meta.sorting_functions.set(name, sorting_function);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.init_sort) {
|
||||||
|
widget.sort(...opts.init_sort);
|
||||||
|
} else {
|
||||||
|
widget.redraw();
|
||||||
|
}
|
||||||
|
|
||||||
// Save the instance for potential future retrieval if a name is provided.
|
// Save the instance for potential future retrieval if a name is provided.
|
||||||
if (opts.name) {
|
if (opts.name) {
|
||||||
DEFAULTS.instances.set(opts.name, widget);
|
DEFAULTS.instances.set(opts.name, widget);
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ exports.populate_emoji = function (emoji_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const emoji_table = $('#admin_emoji_table').expectOne();
|
const emoji_table = $('#admin_emoji_table').expectOne();
|
||||||
const emoji_list = list_render.create(emoji_table, Object.values(emoji_data), {
|
list_render.create(emoji_table, Object.values(emoji_data), {
|
||||||
name: "emoji_list",
|
name: "emoji_list",
|
||||||
modifier: function (item) {
|
modifier: function (item) {
|
||||||
if (item.deactivated !== true) {
|
if (item.deactivated !== true) {
|
||||||
@@ -93,10 +93,11 @@ exports.populate_emoji = function (emoji_data) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
parent_container: $("#emoji-settings").expectOne(),
|
parent_container: $("#emoji-settings").expectOne(),
|
||||||
}).init();
|
sort_fields: {
|
||||||
|
author_full_name: sort_author_full_name,
|
||||||
emoji_list.sort("alphabetic", "name");
|
},
|
||||||
emoji_list.add_sort_function("author_full_name", sort_author_full_name);
|
init_sort: ['alphabetic', 'name'],
|
||||||
|
});
|
||||||
|
|
||||||
loading.destroy_indicator($('#admin_page_emoji_loading_indicator'));
|
loading.destroy_indicator($('#admin_page_emoji_loading_indicator'));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ exports.populate_exports_table = function (exports) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const exports_table = $('#admin_exports_table').expectOne();
|
const exports_table = $('#admin_exports_table').expectOne();
|
||||||
const exports_list = list_render.create(exports_table, Object.values(exports), {
|
list_render.create(exports_table, Object.values(exports), {
|
||||||
name: "admin_exports_list",
|
name: "admin_exports_list",
|
||||||
modifier: function (data) {
|
modifier: function (data) {
|
||||||
if (data.deleted_timestamp === null) {
|
if (data.deleted_timestamp === null) {
|
||||||
@@ -65,11 +65,11 @@ exports.populate_exports_table = function (exports) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
parent_container: $("#data-exports").expectOne(),
|
parent_container: $("#data-exports").expectOne(),
|
||||||
}).init();
|
init_sort: [sort_user],
|
||||||
|
sort_fields: {
|
||||||
exports_list.add_sort_function("user", sort_user);
|
user: sort_user,
|
||||||
|
},
|
||||||
exports_list.sort("user");
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.set_up = function () {
|
exports.set_up = function () {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ function populate_invites(invites_data) {
|
|||||||
|
|
||||||
const invites_table = $("#admin_invites_table").expectOne();
|
const invites_table = $("#admin_invites_table").expectOne();
|
||||||
|
|
||||||
const invites_list = list_render.create(invites_table, invites_data.invites, {
|
list_render.create(invites_table, invites_data.invites, {
|
||||||
name: 'admin_invites_list',
|
name: 'admin_invites_list',
|
||||||
modifier: function (item) {
|
modifier: function (item) {
|
||||||
item.invited_absolute_time = timerender.absolute_time(item.invited * 1000);
|
item.invited_absolute_time = timerender.absolute_time(item.invited * 1000);
|
||||||
@@ -64,11 +64,12 @@ function populate_invites(invites_data) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
parent_container: $("#admin-invites-list").expectOne(),
|
parent_container: $("#admin-invites-list").expectOne(),
|
||||||
|
init_sort: [sort_invitee],
|
||||||
|
sort_fields: {
|
||||||
|
invitee: sort_invitee,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
invites_list.sort('invitee');
|
|
||||||
invites_list.add_sort_function('invitee', sort_invitee);
|
|
||||||
|
|
||||||
loading.destroy_indicator($('#admin_page_invites_loading_indicator'));
|
loading.destroy_indicator($('#admin_page_invites_loading_indicator'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,10 +60,12 @@ exports.populate_filters = function (filters_data) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
parent_container: $("#filter-settings").expectOne(),
|
parent_container: $("#filter-settings").expectOne(),
|
||||||
}).init();
|
init_sort: [sort_pattern],
|
||||||
|
sort_fields: {
|
||||||
filters_list.add_sort_function("pattern", sort_pattern);
|
pattern: sort_pattern,
|
||||||
filters_list.add_sort_function("url", sort_url);
|
url: sort_url,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const active_col = $('.admin_filters_table th.active').expectOne();
|
const active_col = $('.admin_filters_table th.active').expectOne();
|
||||||
filters_list.sort(
|
filters_list.sort(
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ function rerender_ui() {
|
|||||||
is_disabled: settings_config.all_notifications().show_push_notifications_tooltip,
|
is_disabled: settings_config.all_notifications().show_push_notifications_tooltip,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}).init();
|
});
|
||||||
|
|
||||||
if (unmatched_streams.length === 0) {
|
if (unmatched_streams.length === 0) {
|
||||||
unmatched_streams_table.css("display", "none");
|
unmatched_streams_table.css("display", "none");
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ exports.default_code_language_widget = (function (element_id) {
|
|||||||
return item.name.toLowerCase().includes(value);
|
return item.name.toLowerCase().includes(value);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}).init();
|
});
|
||||||
$(`#${element_id} .dropdown-search`).click(function (e) {
|
$(`#${element_id} .dropdown-search`).click(function (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
});
|
});
|
||||||
@@ -451,7 +451,7 @@ exports.populate_notifications_stream_dropdown = function (stream_list) {
|
|||||||
ui.reset_scrollbar(dropdown_list_body);
|
ui.reset_scrollbar(dropdown_list_body);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}).init();
|
});
|
||||||
|
|
||||||
$("#id_realm_notifications_stream .dropdown-search").click(function (e) {
|
$("#id_realm_notifications_stream .dropdown-search").click(function (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -477,7 +477,7 @@ exports.populate_signup_notifications_stream_dropdown = function (stream_list) {
|
|||||||
return item.name.toLowerCase().includes(value);
|
return item.name.toLowerCase().includes(value);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}).init();
|
});
|
||||||
|
|
||||||
$("#id_realm_signup_notifications_stream .dropdown-search").click(function (e) {
|
$("#id_realm_signup_notifications_stream .dropdown-search").click(function (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ exports.build_default_stream_table = function () {
|
|||||||
const stream_ids = stream_data.get_default_stream_ids();
|
const stream_ids = stream_data.get_default_stream_ids();
|
||||||
const subs = stream_ids.map(stream_data.get_sub_by_id);
|
const subs = stream_ids.map(stream_data.get_sub_by_id);
|
||||||
|
|
||||||
const streams_list = list_render.create(table, subs, {
|
list_render.create(table, subs, {
|
||||||
name: "default_streams_list",
|
name: "default_streams_list",
|
||||||
modifier: function (item) {
|
modifier: function (item) {
|
||||||
const row = $(render_admin_default_streams_list({
|
const row = $(render_admin_default_streams_list({
|
||||||
@@ -42,9 +42,8 @@ exports.build_default_stream_table = function () {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
parent_container: $("#admin-default-streams-list").expectOne(),
|
parent_container: $("#admin-default-streams-list").expectOne(),
|
||||||
}).init();
|
init_sort: ['alphabetic', 'name'],
|
||||||
|
});
|
||||||
streams_list.sort("alphabetic", "name");
|
|
||||||
|
|
||||||
loading.destroy_indicator($('#admin_page_default_streams_loading_indicator'));
|
loading.destroy_indicator($('#admin_page_default_streams_loading_indicator'));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ function populate_users(realm_people_data) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const $bots_table = $("#admin_bots_table");
|
const $bots_table = $("#admin_bots_table");
|
||||||
const bot_list = list_render.create($bots_table, bots, {
|
list_render.create($bots_table, bots, {
|
||||||
name: "admin_bot_list",
|
name: "admin_bot_list",
|
||||||
modifier: function (item) {
|
modifier: function (item) {
|
||||||
return render_admin_user_list({
|
return render_admin_user_list({
|
||||||
@@ -203,11 +203,11 @@ function populate_users(realm_people_data) {
|
|||||||
onupdate: reset_scrollbar($bots_table),
|
onupdate: reset_scrollbar($bots_table),
|
||||||
},
|
},
|
||||||
parent_container: $("#admin-bot-list").expectOne(),
|
parent_container: $("#admin-bot-list").expectOne(),
|
||||||
}).init();
|
init_sort: ['alphabetic', 'full_name'],
|
||||||
|
sort_fields: {
|
||||||
bot_list.sort("alphabetic", "full_name");
|
bot_owner: sort_bot_owner,
|
||||||
|
},
|
||||||
bot_list.add_sort_function("bot_owner", sort_bot_owner);
|
});
|
||||||
|
|
||||||
function get_rendered_last_activity(item) {
|
function get_rendered_last_activity(item) {
|
||||||
const today = new XDate();
|
const today = new XDate();
|
||||||
@@ -222,7 +222,7 @@ function populate_users(realm_people_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const $users_table = $("#admin_users_table");
|
const $users_table = $("#admin_users_table");
|
||||||
const users_list = list_render.create($users_table, active_users, {
|
list_render.create($users_table, active_users, {
|
||||||
name: "users_table_list",
|
name: "users_table_list",
|
||||||
modifier: function (item) {
|
modifier: function (item) {
|
||||||
const $row = $(render_admin_user_list({
|
const $row = $(render_admin_user_list({
|
||||||
@@ -240,15 +240,15 @@ function populate_users(realm_people_data) {
|
|||||||
onupdate: reset_scrollbar($users_table),
|
onupdate: reset_scrollbar($users_table),
|
||||||
},
|
},
|
||||||
parent_container: $("#admin-user-list").expectOne(),
|
parent_container: $("#admin-user-list").expectOne(),
|
||||||
}).init();
|
init_sort: ['alphabetic', 'full_name'],
|
||||||
|
sort_fields: {
|
||||||
users_list.sort("alphabetic", "full_name");
|
role: sort_role,
|
||||||
|
last_active: sort_last_active,
|
||||||
users_list.add_sort_function("role", sort_role);
|
},
|
||||||
users_list.add_sort_function("last_active", sort_last_active);
|
});
|
||||||
|
|
||||||
const $deactivated_users_table = $("#admin_deactivated_users_table");
|
const $deactivated_users_table = $("#admin_deactivated_users_table");
|
||||||
const deactivated_users_list = list_render.create($deactivated_users_table, deactivated_users, {
|
list_render.create($deactivated_users_table, deactivated_users, {
|
||||||
name: "deactivated_users_table_list",
|
name: "deactivated_users_table_list",
|
||||||
modifier: function (item) {
|
modifier: function (item) {
|
||||||
return render_admin_user_list({
|
return render_admin_user_list({
|
||||||
@@ -263,10 +263,11 @@ function populate_users(realm_people_data) {
|
|||||||
onupdate: reset_scrollbar($deactivated_users_table),
|
onupdate: reset_scrollbar($deactivated_users_table),
|
||||||
},
|
},
|
||||||
parent_container: $("#admin-deactivated-users-list").expectOne(),
|
parent_container: $("#admin-deactivated-users-list").expectOne(),
|
||||||
}).init();
|
init_sort: ['alphabetic', 'full_name'],
|
||||||
|
sort_fields: {
|
||||||
deactivated_users_list.sort("alphabetic", "full_name");
|
role: sort_role,
|
||||||
deactivated_users_list.add_sort_function("role", sort_role);
|
},
|
||||||
|
});
|
||||||
|
|
||||||
loading.destroy_indicator($('#admin_page_users_loading_indicator'));
|
loading.destroy_indicator($('#admin_page_users_loading_indicator'));
|
||||||
loading.destroy_indicator($('#admin_page_bots_loading_indicator'));
|
loading.destroy_indicator($('#admin_page_bots_loading_indicator'));
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ function show_subscription_settings(sub_row) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}).init();
|
});
|
||||||
|
|
||||||
sub_settings.find('input[name="principal"]').typeahead({
|
sub_settings.find('input[name="principal"]').typeahead({
|
||||||
source: () => stream_data.potential_subscribers(sub),
|
source: () => stream_data.potential_subscribers(sub),
|
||||||
|
|||||||
Reference in New Issue
Block a user