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, ''); };
|
||||
const widget = list_render.create(container, items, opts);
|
||||
widget.init();
|
||||
list_render.create(container, items, opts);
|
||||
|
||||
assert.deepEqual(
|
||||
container.appended_data.html(),
|
||||
@@ -154,7 +153,6 @@ run_test('filtering', () => {
|
||||
|
||||
container.html = (html) => { assert.equal(html, ''); };
|
||||
let widget = list_render.create(container, list, opts);
|
||||
widget.init();
|
||||
|
||||
let expected_html =
|
||||
'<div>apple</div>' +
|
||||
@@ -186,7 +184,7 @@ run_test('filtering', () => {
|
||||
];
|
||||
|
||||
widget.data(new_data);
|
||||
widget.init();
|
||||
widget.redraw();
|
||||
expected_html =
|
||||
'<div>greta</div>' +
|
||||
'<div>gary</div>' +
|
||||
|
||||
@@ -77,7 +77,7 @@ function render_attachments_ui() {
|
||||
const uploaded_files_table = $("#uploaded_files_table").expectOne();
|
||||
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",
|
||||
modifier: function (attachment) {
|
||||
return render_uploaded_files_list({ attachment: attachment });
|
||||
@@ -92,11 +92,12 @@ function render_attachments_ui() {
|
||||
},
|
||||
},
|
||||
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"));
|
||||
}
|
||||
|
||||
|
||||
@@ -50,15 +50,12 @@ exports.create = function ($container, list, opts) {
|
||||
// this memoizes the results and will return a previously invoked
|
||||
// instance
|
||||
if (opts.name && DEFAULTS.instances.get(opts.name)) {
|
||||
// the false flag here means "don't run `init`". This is because a
|
||||
// user is likely reinitializing and will have put .init() afterwards.
|
||||
// This happens when the same codepath is hit multiple times.
|
||||
return DEFAULTS.instances.get(opts.name)
|
||||
.set_container($container)
|
||||
.set_opts(opts)
|
||||
.set_up_event_handlers()
|
||||
.data(list)
|
||||
.init();
|
||||
const old_widget = DEFAULTS.instances.get(opts.name);
|
||||
|
||||
old_widget.data(list);
|
||||
old_widget.redraw();
|
||||
|
||||
return old_widget;
|
||||
}
|
||||
|
||||
const meta = {
|
||||
@@ -129,17 +126,14 @@ exports.create = function ($container, list, opts) {
|
||||
|
||||
$container.append($(html));
|
||||
meta.offset += load_count;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Fills the container with an initial batch of items.
|
||||
// Needs to be enough to exceed the max height, so that a
|
||||
// scrollable area is created.
|
||||
widget.init = function () {
|
||||
this.clear();
|
||||
this.render(DEFAULTS.INITIAL_RENDER_COUNT);
|
||||
return this;
|
||||
widget.redraw = function () {
|
||||
widget.clear();
|
||||
widget.render(DEFAULTS.INITIAL_RENDER_COUNT);
|
||||
};
|
||||
|
||||
widget.filter = function (map_function) {
|
||||
@@ -169,40 +163,21 @@ exports.create = function ($container, list, opts) {
|
||||
|
||||
widget.clear();
|
||||
|
||||
return this;
|
||||
return;
|
||||
}
|
||||
|
||||
blueslip.warn("The data object provided to the progressive" +
|
||||
" list render is invalid");
|
||||
return this;
|
||||
};
|
||||
|
||||
widget.clear = function () {
|
||||
$container.html("");
|
||||
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 () {
|
||||
meta.filtered_list.reverse();
|
||||
widget.init();
|
||||
return this;
|
||||
widget.redraw();
|
||||
};
|
||||
|
||||
// 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) {
|
||||
// clear and re-initialize the list with the newly filtered subset
|
||||
// of items.
|
||||
widget.init();
|
||||
widget.redraw();
|
||||
|
||||
if (opts.filter && 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
|
||||
// and perform a sort on it with the given 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.
|
||||
// it will then also not run an update in the DOM (because we
|
||||
// pass `true`), because it will update regardless below at
|
||||
// `widget.init()`.
|
||||
// `widget.redraw()`.
|
||||
widget.sort(undefined, meta.prop, true);
|
||||
filter_list(value);
|
||||
|
||||
// clear and re-initialize the list with the newly filtered subset
|
||||
// of items.
|
||||
widget.init();
|
||||
widget.redraw();
|
||||
|
||||
if (opts.filter.onupdate) {
|
||||
opts.filter.onupdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// add built-in generic sort functions.
|
||||
@@ -344,6 +313,18 @@ exports.create = function ($container, list, opts) {
|
||||
|
||||
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.
|
||||
if (opts.name) {
|
||||
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_list = list_render.create(emoji_table, Object.values(emoji_data), {
|
||||
list_render.create(emoji_table, Object.values(emoji_data), {
|
||||
name: "emoji_list",
|
||||
modifier: function (item) {
|
||||
if (item.deactivated !== true) {
|
||||
@@ -93,10 +93,11 @@ exports.populate_emoji = function (emoji_data) {
|
||||
},
|
||||
},
|
||||
parent_container: $("#emoji-settings").expectOne(),
|
||||
}).init();
|
||||
|
||||
emoji_list.sort("alphabetic", "name");
|
||||
emoji_list.add_sort_function("author_full_name", sort_author_full_name);
|
||||
sort_fields: {
|
||||
author_full_name: sort_author_full_name,
|
||||
},
|
||||
init_sort: ['alphabetic', 'name'],
|
||||
});
|
||||
|
||||
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_list = list_render.create(exports_table, Object.values(exports), {
|
||||
list_render.create(exports_table, Object.values(exports), {
|
||||
name: "admin_exports_list",
|
||||
modifier: function (data) {
|
||||
if (data.deleted_timestamp === null) {
|
||||
@@ -65,11 +65,11 @@ exports.populate_exports_table = function (exports) {
|
||||
},
|
||||
},
|
||||
parent_container: $("#data-exports").expectOne(),
|
||||
}).init();
|
||||
|
||||
exports_list.add_sort_function("user", sort_user);
|
||||
|
||||
exports_list.sort("user");
|
||||
init_sort: [sort_user],
|
||||
sort_fields: {
|
||||
user: sort_user,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
exports.set_up = function () {
|
||||
|
||||
@@ -46,7 +46,7 @@ function populate_invites(invites_data) {
|
||||
|
||||
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',
|
||||
modifier: function (item) {
|
||||
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(),
|
||||
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'));
|
||||
}
|
||||
|
||||
|
||||
@@ -60,10 +60,12 @@ exports.populate_filters = function (filters_data) {
|
||||
},
|
||||
},
|
||||
parent_container: $("#filter-settings").expectOne(),
|
||||
}).init();
|
||||
|
||||
filters_list.add_sort_function("pattern", sort_pattern);
|
||||
filters_list.add_sort_function("url", sort_url);
|
||||
init_sort: [sort_pattern],
|
||||
sort_fields: {
|
||||
pattern: sort_pattern,
|
||||
url: sort_url,
|
||||
},
|
||||
});
|
||||
|
||||
const active_col = $('.admin_filters_table th.active').expectOne();
|
||||
filters_list.sort(
|
||||
|
||||
@@ -57,7 +57,7 @@ function rerender_ui() {
|
||||
is_disabled: settings_config.all_notifications().show_push_notifications_tooltip,
|
||||
});
|
||||
},
|
||||
}).init();
|
||||
});
|
||||
|
||||
if (unmatched_streams.length === 0) {
|
||||
unmatched_streams_table.css("display", "none");
|
||||
|
||||
@@ -34,7 +34,7 @@ exports.default_code_language_widget = (function (element_id) {
|
||||
return item.name.toLowerCase().includes(value);
|
||||
},
|
||||
},
|
||||
}).init();
|
||||
});
|
||||
$(`#${element_id} .dropdown-search`).click(function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
@@ -451,7 +451,7 @@ exports.populate_notifications_stream_dropdown = function (stream_list) {
|
||||
ui.reset_scrollbar(dropdown_list_body);
|
||||
},
|
||||
},
|
||||
}).init();
|
||||
});
|
||||
|
||||
$("#id_realm_notifications_stream .dropdown-search").click(function (e) {
|
||||
e.stopPropagation();
|
||||
@@ -477,7 +477,7 @@ exports.populate_signup_notifications_stream_dropdown = function (stream_list) {
|
||||
return item.name.toLowerCase().includes(value);
|
||||
},
|
||||
},
|
||||
}).init();
|
||||
});
|
||||
|
||||
$("#id_realm_signup_notifications_stream .dropdown-search").click(function (e) {
|
||||
e.stopPropagation();
|
||||
|
||||
@@ -23,7 +23,7 @@ exports.build_default_stream_table = function () {
|
||||
const stream_ids = stream_data.get_default_stream_ids();
|
||||
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",
|
||||
modifier: function (item) {
|
||||
const row = $(render_admin_default_streams_list({
|
||||
@@ -42,9 +42,8 @@ exports.build_default_stream_table = function () {
|
||||
},
|
||||
},
|
||||
parent_container: $("#admin-default-streams-list").expectOne(),
|
||||
}).init();
|
||||
|
||||
streams_list.sort("alphabetic", "name");
|
||||
init_sort: ['alphabetic', 'name'],
|
||||
});
|
||||
|
||||
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 bot_list = list_render.create($bots_table, bots, {
|
||||
list_render.create($bots_table, bots, {
|
||||
name: "admin_bot_list",
|
||||
modifier: function (item) {
|
||||
return render_admin_user_list({
|
||||
@@ -203,11 +203,11 @@ function populate_users(realm_people_data) {
|
||||
onupdate: reset_scrollbar($bots_table),
|
||||
},
|
||||
parent_container: $("#admin-bot-list").expectOne(),
|
||||
}).init();
|
||||
|
||||
bot_list.sort("alphabetic", "full_name");
|
||||
|
||||
bot_list.add_sort_function("bot_owner", sort_bot_owner);
|
||||
init_sort: ['alphabetic', 'full_name'],
|
||||
sort_fields: {
|
||||
bot_owner: sort_bot_owner,
|
||||
},
|
||||
});
|
||||
|
||||
function get_rendered_last_activity(item) {
|
||||
const today = new XDate();
|
||||
@@ -222,7 +222,7 @@ function populate_users(realm_people_data) {
|
||||
}
|
||||
|
||||
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",
|
||||
modifier: function (item) {
|
||||
const $row = $(render_admin_user_list({
|
||||
@@ -240,15 +240,15 @@ function populate_users(realm_people_data) {
|
||||
onupdate: reset_scrollbar($users_table),
|
||||
},
|
||||
parent_container: $("#admin-user-list").expectOne(),
|
||||
}).init();
|
||||
|
||||
users_list.sort("alphabetic", "full_name");
|
||||
|
||||
users_list.add_sort_function("role", sort_role);
|
||||
users_list.add_sort_function("last_active", sort_last_active);
|
||||
init_sort: ['alphabetic', 'full_name'],
|
||||
sort_fields: {
|
||||
role: sort_role,
|
||||
last_active: sort_last_active,
|
||||
},
|
||||
});
|
||||
|
||||
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",
|
||||
modifier: function (item) {
|
||||
return render_admin_user_list({
|
||||
@@ -263,10 +263,11 @@ function populate_users(realm_people_data) {
|
||||
onupdate: reset_scrollbar($deactivated_users_table),
|
||||
},
|
||||
parent_container: $("#admin-deactivated-users-list").expectOne(),
|
||||
}).init();
|
||||
|
||||
deactivated_users_list.sort("alphabetic", "full_name");
|
||||
deactivated_users_list.add_sort_function("role", sort_role);
|
||||
init_sort: ['alphabetic', 'full_name'],
|
||||
sort_fields: {
|
||||
role: sort_role,
|
||||
},
|
||||
});
|
||||
|
||||
loading.destroy_indicator($('#admin_page_users_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({
|
||||
source: () => stream_data.potential_subscribers(sub),
|
||||
|
||||
Reference in New Issue
Block a user