mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	Rename list_render -> ListWidget.
Similar to DropdownListWidget, list_render is actually a widget. The changed case more accurately represents how its supposed to be used as a Class.
This commit is contained in:
		
				
					committed by
					
						
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							69890f36b1
						
					
				
				
					commit
					75a0fa5b91
				
			@@ -168,8 +168,8 @@
 | 
				
			|||||||
                "jQuery": false,
 | 
					                "jQuery": false,
 | 
				
			||||||
                "keydown_util": false,
 | 
					                "keydown_util": false,
 | 
				
			||||||
                "lightbox": false,
 | 
					                "lightbox": false,
 | 
				
			||||||
                "list_render": false,
 | 
					 | 
				
			||||||
                "list_util": false,
 | 
					                "list_util": false,
 | 
				
			||||||
 | 
					                "ListWidget": false,
 | 
				
			||||||
                "loading": false,
 | 
					                "loading": false,
 | 
				
			||||||
                "localStorage": false,
 | 
					                "localStorage": false,
 | 
				
			||||||
                "local_message": false,
 | 
					                "local_message": false,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,10 +11,10 @@ zrequire("scroll_util");
 | 
				
			|||||||
set_global("$", make_zjquery());
 | 
					set_global("$", make_zjquery());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const noop = () => {};
 | 
					const noop = () => {};
 | 
				
			||||||
const _list_render = {
 | 
					const _ListWidget = {
 | 
				
			||||||
    create: () => ({init: noop}),
 | 
					    create: () => ({init: noop}),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
set_global("list_render", _list_render);
 | 
					set_global("ListWidget", _ListWidget);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const setup_zjquery_data = (name) => {
 | 
					const setup_zjquery_data = (name) => {
 | 
				
			||||||
    $.clear_all_elements();
 | 
					    $.clear_all_elements();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,10 +5,10 @@ const {strict: assert} = require("assert");
 | 
				
			|||||||
const {set_global, zrequire} = require("../zjsunit/namespace");
 | 
					const {set_global, zrequire} = require("../zjsunit/namespace");
 | 
				
			||||||
const {run_test} = require("../zjsunit/test");
 | 
					const {run_test} = require("../zjsunit/test");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
zrequire("list_render");
 | 
					zrequire("list_widget");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// We need these stubs to get by instanceof checks.
 | 
					// We need these stubs to get by instanceof checks.
 | 
				
			||||||
// The list_render library allows you to insert objects
 | 
					// The ListWidget library allows you to insert objects
 | 
				
			||||||
// that are either jQuery, Element, or just raw HTML
 | 
					// that are either jQuery, Element, or just raw HTML
 | 
				
			||||||
// strings.  We initially test with raw strings.
 | 
					// strings.  We initially test with raw strings.
 | 
				
			||||||
set_global("jQuery", "stub");
 | 
					set_global("jQuery", "stub");
 | 
				
			||||||
@@ -168,7 +168,7 @@ run_test("scrolling", () => {
 | 
				
			|||||||
    container.html = (html) => {
 | 
					    container.html = (html) => {
 | 
				
			||||||
        assert.equal(html, "");
 | 
					        assert.equal(html, "");
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    list_render.create(container, items, opts);
 | 
					    ListWidget.create(container, items, opts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert.deepEqual(container.appended_data.html(), items.slice(0, 80).join(""));
 | 
					    assert.deepEqual(container.appended_data.html(), items.slice(0, 80).join(""));
 | 
				
			||||||
    assert.equal(get_scroll_element_called, true);
 | 
					    assert.equal(get_scroll_element_called, true);
 | 
				
			||||||
@@ -203,7 +203,7 @@ run_test("filtering", () => {
 | 
				
			|||||||
    container.html = (html) => {
 | 
					    container.html = (html) => {
 | 
				
			||||||
        assert.equal(html, "");
 | 
					        assert.equal(html, "");
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    const widget = list_render.create(container, list, opts);
 | 
					    const widget = ListWidget.create(container, list, opts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let expected_html =
 | 
					    let expected_html =
 | 
				
			||||||
        "<div>apple</div>" +
 | 
					        "<div>apple</div>" +
 | 
				
			||||||
@@ -242,7 +242,7 @@ run_test("no filtering", () => {
 | 
				
			|||||||
        modifier: (item) => div(item),
 | 
					        modifier: (item) => div(item),
 | 
				
			||||||
        simplebar_container: scroll_container,
 | 
					        simplebar_container: scroll_container,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    const widget = list_render.create(container, ["apple", "banana"], opts);
 | 
					    const widget = ListWidget.create(container, ["apple", "banana"], opts);
 | 
				
			||||||
    widget.render();
 | 
					    widget.render();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const expected_html = "<div>apple</div><div>banana</div>";
 | 
					    const expected_html = "<div>apple</div><div>banana</div>";
 | 
				
			||||||
@@ -278,7 +278,7 @@ function sort_button(opts) {
 | 
				
			|||||||
    const button = {
 | 
					    const button = {
 | 
				
			||||||
        data,
 | 
					        data,
 | 
				
			||||||
        closest: lookup(".progressive-table-wrapper", {
 | 
					        closest: lookup(".progressive-table-wrapper", {
 | 
				
			||||||
            data: lookup("list-render", opts.list_name),
 | 
					            data: lookup("list-widget", opts.list_name),
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
        addClass: (cls) => {
 | 
					        addClass: (cls) => {
 | 
				
			||||||
            classList.add(cls);
 | 
					            classList.add(cls);
 | 
				
			||||||
@@ -319,7 +319,7 @@ run_test("wire up filter element", () => {
 | 
				
			|||||||
        simplebar_container: scroll_container,
 | 
					        simplebar_container: scroll_container,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    list_render.create(container, lst, opts);
 | 
					    ListWidget.create(container, lst, opts);
 | 
				
			||||||
    filter_element.f.apply({value: "se"});
 | 
					    filter_element.f.apply({value: "se"});
 | 
				
			||||||
    assert.equal(container.appended_data.html(), "(JESSE)(moses)(Sean)");
 | 
					    assert.equal(container.appended_data.html(), "(JESSE)(moses)(Sean)");
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
@@ -357,7 +357,7 @@ run_test("sorting", () => {
 | 
				
			|||||||
        return people.map((item) => opts.modifier(item)).join("");
 | 
					        return people.map((item) => opts.modifier(item)).join("");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    list_render.create(container, list, opts);
 | 
					    ListWidget.create(container, list, opts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let button_opts;
 | 
					    let button_opts;
 | 
				
			||||||
    let button;
 | 
					    let button;
 | 
				
			||||||
@@ -445,7 +445,7 @@ run_test("custom sort", () => {
 | 
				
			|||||||
        return a.x * a.y - b.x * b.y;
 | 
					        return a.x * a.y - b.x * b.y;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    list_render.create(container, list, {
 | 
					    ListWidget.create(container, list, {
 | 
				
			||||||
        name: "custom-sort-list",
 | 
					        name: "custom-sort-list",
 | 
				
			||||||
        modifier: (n) => "(" + n.x + ", " + n.y + ")",
 | 
					        modifier: (n) => "(" + n.x + ", " + n.y + ")",
 | 
				
			||||||
        sort_fields: {
 | 
					        sort_fields: {
 | 
				
			||||||
@@ -458,7 +458,7 @@ run_test("custom sort", () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    assert.deepEqual(container.appended_data.html(), "(6, 7)(1, 43)(4, 11)");
 | 
					    assert.deepEqual(container.appended_data.html(), "(6, 7)(1, 43)(4, 11)");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const widget = list_render.get("custom-sort-list");
 | 
					    const widget = ListWidget.get("custom-sort-list");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    widget.sort("x_value");
 | 
					    widget.sort("x_value");
 | 
				
			||||||
    assert.deepEqual(container.appended_data.html(), "(1, 43)(4, 11)(6, 7)");
 | 
					    assert.deepEqual(container.appended_data.html(), "(1, 43)(4, 11)(6, 7)");
 | 
				
			||||||
@@ -494,13 +494,13 @@ run_test("clear_event_handlers", () => {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Create it the first time.
 | 
					    // Create it the first time.
 | 
				
			||||||
    list_render.create(container, list, opts);
 | 
					    ListWidget.create(container, list, opts);
 | 
				
			||||||
    assert.equal(sort_container.cleared, false);
 | 
					    assert.equal(sort_container.cleared, false);
 | 
				
			||||||
    assert.equal(scroll_container.cleared, false);
 | 
					    assert.equal(scroll_container.cleared, false);
 | 
				
			||||||
    assert.equal(filter_element.cleared, false);
 | 
					    assert.equal(filter_element.cleared, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // The second time we'll clear the old events.
 | 
					    // The second time we'll clear the old events.
 | 
				
			||||||
    list_render.create(container, list, opts);
 | 
					    ListWidget.create(container, list, opts);
 | 
				
			||||||
    assert.equal(sort_container.cleared, true);
 | 
					    assert.equal(sort_container.cleared, true);
 | 
				
			||||||
    assert.equal(scroll_container.cleared, true);
 | 
					    assert.equal(scroll_container.cleared, true);
 | 
				
			||||||
    assert.equal(filter_element.cleared, true);
 | 
					    assert.equal(filter_element.cleared, true);
 | 
				
			||||||
@@ -513,24 +513,24 @@ run_test("errors", () => {
 | 
				
			|||||||
    const scroll_container = make_scroll_container();
 | 
					    const scroll_container = make_scroll_container();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    blueslip.expect("error", "Need opts to create widget.");
 | 
					    blueslip.expect("error", "Need opts to create widget.");
 | 
				
			||||||
    list_render.create(container, list);
 | 
					    ListWidget.create(container, list);
 | 
				
			||||||
    blueslip.reset();
 | 
					    blueslip.reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    blueslip.expect("error", "simplebar_container is missing.");
 | 
					    blueslip.expect("error", "simplebar_container is missing.");
 | 
				
			||||||
    list_render.create(container, list, {
 | 
					    ListWidget.create(container, list, {
 | 
				
			||||||
        modifier: "hello world",
 | 
					        modifier: "hello world",
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    blueslip.reset();
 | 
					    blueslip.reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    blueslip.expect("error", "get_item should be a function");
 | 
					    blueslip.expect("error", "get_item should be a function");
 | 
				
			||||||
    list_render.create(container, list, {
 | 
					    ListWidget.create(container, list, {
 | 
				
			||||||
        get_item: "not a function",
 | 
					        get_item: "not a function",
 | 
				
			||||||
        simplebar_container: scroll_container,
 | 
					        simplebar_container: scroll_container,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    blueslip.reset();
 | 
					    blueslip.reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    blueslip.expect("error", "Filter predicate is not a function.");
 | 
					    blueslip.expect("error", "Filter predicate is not a function.");
 | 
				
			||||||
    list_render.create(container, list, {
 | 
					    ListWidget.create(container, list, {
 | 
				
			||||||
        filter: {
 | 
					        filter: {
 | 
				
			||||||
            predicate: "wrong type",
 | 
					            predicate: "wrong type",
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
@@ -539,7 +539,7 @@ run_test("errors", () => {
 | 
				
			|||||||
    blueslip.reset();
 | 
					    blueslip.reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    blueslip.expect("error", "Filterer and predicate are mutually exclusive.");
 | 
					    blueslip.expect("error", "Filterer and predicate are mutually exclusive.");
 | 
				
			||||||
    list_render.create(container, list, {
 | 
					    ListWidget.create(container, list, {
 | 
				
			||||||
        filter: {
 | 
					        filter: {
 | 
				
			||||||
            filterer: () => true,
 | 
					            filterer: () => true,
 | 
				
			||||||
            predicate: () => true,
 | 
					            predicate: () => true,
 | 
				
			||||||
@@ -549,7 +549,7 @@ run_test("errors", () => {
 | 
				
			|||||||
    blueslip.reset();
 | 
					    blueslip.reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    blueslip.expect("error", "Filter filterer is not a function (or missing).");
 | 
					    blueslip.expect("error", "Filter filterer is not a function (or missing).");
 | 
				
			||||||
    list_render.create(container, list, {
 | 
					    ListWidget.create(container, list, {
 | 
				
			||||||
        filter: {},
 | 
					        filter: {},
 | 
				
			||||||
        simplebar_container: scroll_container,
 | 
					        simplebar_container: scroll_container,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@@ -557,7 +557,7 @@ run_test("errors", () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    container.html = () => {};
 | 
					    container.html = () => {};
 | 
				
			||||||
    blueslip.expect("error", "List item is not a string: 999");
 | 
					    blueslip.expect("error", "List item is not a string: 999");
 | 
				
			||||||
    list_render.create(container, list, {
 | 
					    ListWidget.create(container, list, {
 | 
				
			||||||
        modifier: () => 999,
 | 
					        modifier: () => 999,
 | 
				
			||||||
        simplebar_container: scroll_container,
 | 
					        simplebar_container: scroll_container,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@@ -575,8 +575,8 @@ run_test("sort helpers", () => {
 | 
				
			|||||||
    const bob2 = {name: "bob", id: 2};
 | 
					    const bob2 = {name: "bob", id: 2};
 | 
				
			||||||
    const bob10 = {name: "bob", id: 10};
 | 
					    const bob10 = {name: "bob", id: 10};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const alpha_cmp = list_render.alphabetic_sort("name");
 | 
					    const alpha_cmp = ListWidget.alphabetic_sort("name");
 | 
				
			||||||
    const num_cmp = list_render.numeric_sort("id");
 | 
					    const num_cmp = ListWidget.numeric_sort("id");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert.equal(alpha_cmp(alice2, alice10), 0);
 | 
					    assert.equal(alpha_cmp(alice2, alice10), 0);
 | 
				
			||||||
    assert.equal(alpha_cmp(alice2, bob2), -1);
 | 
					    assert.equal(alpha_cmp(alice2, bob2), -1);
 | 
				
			||||||
@@ -594,7 +594,7 @@ run_test("replace_list_data w/filter update", () => {
 | 
				
			|||||||
    const list = [1, 2, 3, 4];
 | 
					    const list = [1, 2, 3, 4];
 | 
				
			||||||
    let num_updates = 0;
 | 
					    let num_updates = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    list_render.create(container, list, {
 | 
					    ListWidget.create(container, list, {
 | 
				
			||||||
        name: "replace-list",
 | 
					        name: "replace-list",
 | 
				
			||||||
        modifier: (n) => "(" + n.toString() + ")",
 | 
					        modifier: (n) => "(" + n.toString() + ")",
 | 
				
			||||||
        filter: {
 | 
					        filter: {
 | 
				
			||||||
@@ -610,7 +610,7 @@ run_test("replace_list_data w/filter update", () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    assert.deepEqual(container.appended_data.html(), "(2)(4)");
 | 
					    assert.deepEqual(container.appended_data.html(), "(2)(4)");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const widget = list_render.get("replace-list");
 | 
					    const widget = ListWidget.get("replace-list");
 | 
				
			||||||
    widget.replace_list_data([5, 6, 7, 8]);
 | 
					    widget.replace_list_data([5, 6, 7, 8]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert.equal(num_updates, 1);
 | 
					    assert.equal(num_updates, 1);
 | 
				
			||||||
@@ -632,7 +632,7 @@ run_test("opts.get_item", () => {
 | 
				
			|||||||
        get_item: (n) => items[n],
 | 
					        get_item: (n) => items[n],
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert.deepEqual(list_render.get_filtered_items("whatever", list, boring_opts), [
 | 
					    assert.deepEqual(ListWidget.get_filtered_items("whatever", list, boring_opts), [
 | 
				
			||||||
        "one",
 | 
					        "one",
 | 
				
			||||||
        "two",
 | 
					        "two",
 | 
				
			||||||
        "three",
 | 
					        "three",
 | 
				
			||||||
@@ -648,7 +648,7 @@ run_test("opts.get_item", () => {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert.deepEqual(list_render.get_filtered_items("t", list, predicate_opts), ["two", "three"]);
 | 
					    assert.deepEqual(ListWidget.get_filtered_items("t", list, predicate_opts), ["two", "three"]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const filterer_opts = {
 | 
					    const filterer_opts = {
 | 
				
			||||||
        get_item: (n) => items[n],
 | 
					        get_item: (n) => items[n],
 | 
				
			||||||
@@ -657,7 +657,7 @@ run_test("opts.get_item", () => {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert.deepEqual(list_render.get_filtered_items("t", list, filterer_opts), ["two", "three"]);
 | 
					    assert.deepEqual(ListWidget.get_filtered_items("t", list, filterer_opts), ["two", "three"]);
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
run_test("render item", () => {
 | 
					run_test("render item", () => {
 | 
				
			||||||
@@ -695,7 +695,7 @@ run_test("render item", () => {
 | 
				
			|||||||
    let text = "initial";
 | 
					    let text = "initial";
 | 
				
			||||||
    const get_item = (item) => ({text: `${text}: ${item}`, value: item});
 | 
					    const get_item = (item) => ({text: `${text}: ${item}`, value: item});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const widget = list_render.create(container, list, {
 | 
					    const widget = ListWidget.create(container, list, {
 | 
				
			||||||
        name: "replace-list",
 | 
					        name: "replace-list",
 | 
				
			||||||
        modifier: (item) => `<tr data-item=${item.value}>${item.text}</tr>\n`,
 | 
					        modifier: (item) => `<tr data-item=${item.value}>${item.text}</tr>\n`,
 | 
				
			||||||
        get_item,
 | 
					        get_item,
 | 
				
			||||||
@@ -730,7 +730,7 @@ run_test("render item", () => {
 | 
				
			|||||||
    // Tests below this are for the corner cases, where we abort the rerender.
 | 
					    // Tests below this are for the corner cases, where we abort the rerender.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    blueslip.expect("error", "html_selector should be a function.");
 | 
					    blueslip.expect("error", "html_selector should be a function.");
 | 
				
			||||||
    list_render.create(container, list, {
 | 
					    ListWidget.create(container, list, {
 | 
				
			||||||
        name: "replace-list",
 | 
					        name: "replace-list",
 | 
				
			||||||
        modifier: (item) => `<tr data-item=${item.value}>${item.text}</tr>\n`,
 | 
					        modifier: (item) => `<tr data-item=${item.value}>${item.text}</tr>\n`,
 | 
				
			||||||
        get_item,
 | 
					        get_item,
 | 
				
			||||||
@@ -740,7 +740,7 @@ run_test("render item", () => {
 | 
				
			|||||||
    blueslip.reset();
 | 
					    blueslip.reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let get_item_called;
 | 
					    let get_item_called;
 | 
				
			||||||
    const widget_2 = list_render.create(container, list, {
 | 
					    const widget_2 = ListWidget.create(container, list, {
 | 
				
			||||||
        name: "replace-list",
 | 
					        name: "replace-list",
 | 
				
			||||||
        modifier: (item) => `<tr data-item=${item.value}>${item.text}</tr>\n`,
 | 
					        modifier: (item) => `<tr data-item=${item.value}>${item.text}</tr>\n`,
 | 
				
			||||||
        get_item: (item) => {
 | 
					        get_item: (item) => {
 | 
				
			||||||
@@ -755,7 +755,7 @@ run_test("render item", () => {
 | 
				
			|||||||
    assert(!get_item_called);
 | 
					    assert(!get_item_called);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let rendering_item = false;
 | 
					    let rendering_item = false;
 | 
				
			||||||
    const widget_3 = list_render.create(container, list, {
 | 
					    const widget_3 = ListWidget.create(container, list, {
 | 
				
			||||||
        name: "replace-list",
 | 
					        name: "replace-list",
 | 
				
			||||||
        modifier: (item) => (rendering_item ? undefined : `${item}\n`),
 | 
					        modifier: (item) => (rendering_item ? undefined : `${item}\n`),
 | 
				
			||||||
        get_item,
 | 
					        get_item,
 | 
				
			||||||
@@ -55,17 +55,17 @@ set_global("hash_util", {
 | 
				
			|||||||
set_global("recent_senders", {
 | 
					set_global("recent_senders", {
 | 
				
			||||||
    get_topic_recent_senders: () => [1, 2],
 | 
					    get_topic_recent_senders: () => [1, 2],
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
set_global("list_render", {
 | 
					set_global("ListWidget", {
 | 
				
			||||||
    modifier: noop,
 | 
					    modifier: noop,
 | 
				
			||||||
    create: (container, mapped_topic_values, opts) => {
 | 
					    create: (container, mapped_topic_values, opts) => {
 | 
				
			||||||
        const formatted_topics = [];
 | 
					        const formatted_topics = [];
 | 
				
			||||||
        list_render.modifier = opts.modifier;
 | 
					        ListWidget.modifier = opts.modifier;
 | 
				
			||||||
        for (const item of mapped_topic_values) {
 | 
					        for (const item of mapped_topic_values) {
 | 
				
			||||||
            formatted_topics.push(opts.modifier(item));
 | 
					            formatted_topics.push(opts.modifier(item));
 | 
				
			||||||
            opts.filter.predicate(item);
 | 
					            opts.filter.predicate(item);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // Just for coverage, the mechanisms
 | 
					        // Just for coverage, the mechanisms
 | 
				
			||||||
        // are tested in list_render
 | 
					        // are tested in list_widget.js
 | 
				
			||||||
        if (mapped_topic_values.length >= 2) {
 | 
					        if (mapped_topic_values.length >= 2) {
 | 
				
			||||||
            opts.sort_fields.stream_sort(mapped_topic_values[0], mapped_topic_values[1]);
 | 
					            opts.sort_fields.stream_sort(mapped_topic_values[0], mapped_topic_values[1]);
 | 
				
			||||||
            opts.sort_fields.stream_sort(mapped_topic_values[1], mapped_topic_values[0]);
 | 
					            opts.sort_fields.stream_sort(mapped_topic_values[1], mapped_topic_values[0]);
 | 
				
			||||||
@@ -74,10 +74,10 @@ set_global("list_render", {
 | 
				
			|||||||
            opts.sort_fields.topic_sort(mapped_topic_values[1], mapped_topic_values[0]);
 | 
					            opts.sort_fields.topic_sort(mapped_topic_values[1], mapped_topic_values[0]);
 | 
				
			||||||
            opts.sort_fields.topic_sort(mapped_topic_values[0], mapped_topic_values[0]);
 | 
					            opts.sort_fields.topic_sort(mapped_topic_values[0], mapped_topic_values[0]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return list_render;
 | 
					        return ListWidget;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    hard_redraw: noop,
 | 
					    hard_redraw: noop,
 | 
				
			||||||
    render_item: (item) => list_render.modifier(item),
 | 
					    render_item: (item) => ListWidget.modifier(item),
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Custom Data
 | 
					// Custom Data
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,7 +68,7 @@ const _realm_logo = {
 | 
				
			|||||||
    build_realm_logo_widget: noop,
 | 
					    build_realm_logo_widget: noop,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const _list_render = {
 | 
					const _ListWidget = {
 | 
				
			||||||
    create: () => ({init: noop}),
 | 
					    create: () => ({init: noop}),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -82,7 +82,7 @@ set_global("page_params", _page_params);
 | 
				
			|||||||
set_global("realm_icon", _realm_icon);
 | 
					set_global("realm_icon", _realm_icon);
 | 
				
			||||||
set_global("realm_logo", _realm_logo);
 | 
					set_global("realm_logo", _realm_logo);
 | 
				
			||||||
set_global("ui_report", _ui_report);
 | 
					set_global("ui_report", _ui_report);
 | 
				
			||||||
set_global("list_render", _list_render);
 | 
					set_global("ListWidget", _ListWidget);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const settings_config = zrequire("settings_config");
 | 
					const settings_config = zrequire("settings_config");
 | 
				
			||||||
const settings_bots = zrequire("settings_bots");
 | 
					const settings_bots = zrequire("settings_bots");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ set_global("hash_util", {
 | 
				
			|||||||
    stream_edit_uri: noop,
 | 
					    stream_edit_uri: noop,
 | 
				
			||||||
    by_stream_uri: noop,
 | 
					    by_stream_uri: noop,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
set_global("list_render", {
 | 
					set_global("ListWidget", {
 | 
				
			||||||
    create: () => ({init: noop}),
 | 
					    create: () => ({init: noop}),
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
set_global("page_params", {});
 | 
					set_global("page_params", {});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -85,7 +85,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");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    list_render.create(uploaded_files_table, attachments, {
 | 
					    ListWidget.create(uploaded_files_table, attachments, {
 | 
				
			||||||
        name: "uploaded-files-list",
 | 
					        name: "uploaded-files-list",
 | 
				
			||||||
        modifier(attachment) {
 | 
					        modifier(attachment) {
 | 
				
			||||||
            return render_uploaded_files_list({attachment});
 | 
					            return render_uploaded_files_list({attachment});
 | 
				
			||||||
@@ -132,7 +132,7 @@ exports.update_attachments = function (event) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    upload_space_used = event.upload_space_used;
 | 
					    upload_space_used = event.upload_space_used;
 | 
				
			||||||
    // TODO: This is inefficient and we should be able to do some sort
 | 
					    // TODO: This is inefficient and we should be able to do some sort
 | 
				
			||||||
    // of incremental list_render update instead.
 | 
					    // of incremental ListWidget update instead.
 | 
				
			||||||
    render_attachments_ui();
 | 
					    render_attachments_ui();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -95,7 +95,7 @@ import "../message_edit";
 | 
				
			|||||||
import "../message_edit_history";
 | 
					import "../message_edit_history";
 | 
				
			||||||
import "../condense";
 | 
					import "../condense";
 | 
				
			||||||
import "../resize";
 | 
					import "../resize";
 | 
				
			||||||
import "../list_render";
 | 
					import "../list_widget";
 | 
				
			||||||
import "../floating_recipient_bar";
 | 
					import "../floating_recipient_bar";
 | 
				
			||||||
import "../lightbox";
 | 
					import "../lightbox";
 | 
				
			||||||
import "../ui_report";
 | 
					import "../ui_report";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -74,7 +74,7 @@ const DropdownListWidget = function (opts) {
 | 
				
			|||||||
        const search_input = $(`#${opts.container_id} .dropdown-search > input[type=text]`);
 | 
					        const search_input = $(`#${opts.container_id} .dropdown-search > input[type=text]`);
 | 
				
			||||||
        const dropdown_toggle = $(`#${opts.container_id} .dropdown-toggle`);
 | 
					        const dropdown_toggle = $(`#${opts.container_id} .dropdown-toggle`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        list_render.create(dropdown_list_body, opts.data, {
 | 
					        ListWidget.create(dropdown_list_body, opts.data, {
 | 
				
			||||||
            name: `${opts.widget_name}_list`,
 | 
					            name: `${opts.widget_name}_list`,
 | 
				
			||||||
            modifier(item) {
 | 
					            modifier(item) {
 | 
				
			||||||
                return render_dropdown_list({item});
 | 
					                return render_dropdown_list({item});
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								static/js/global.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								static/js/global.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -60,8 +60,8 @@ declare let input_pill: any;
 | 
				
			|||||||
declare let invite: any;
 | 
					declare let invite: any;
 | 
				
			||||||
declare let keydown_util: any;
 | 
					declare let keydown_util: any;
 | 
				
			||||||
declare let lightbox: any;
 | 
					declare let lightbox: any;
 | 
				
			||||||
declare let list_render: any;
 | 
					 | 
				
			||||||
declare let list_util: any;
 | 
					declare let list_util: any;
 | 
				
			||||||
 | 
					declare let list_widget: any;
 | 
				
			||||||
declare let loading: any;
 | 
					declare let loading: any;
 | 
				
			||||||
declare let local_message: any;
 | 
					declare let local_message: any;
 | 
				
			||||||
declare let localstorage: any;
 | 
					declare let localstorage: any;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,8 +7,7 @@ const DEFAULTS = {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ----------------------------------------------------
 | 
					// ----------------------------------------------------
 | 
				
			||||||
// This function describes (programmatically) how to use
 | 
					// This function describes (programmatically) how to use the ListWidget.
 | 
				
			||||||
// the list_render widget.
 | 
					 | 
				
			||||||
// ----------------------------------------------------
 | 
					// ----------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
exports.validate_opts = (opts) => {
 | 
					exports.validate_opts = (opts) => {
 | 
				
			||||||
@@ -187,7 +186,7 @@ exports.create = function ($container, list, opts) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        const slice = meta.filtered_list.slice(meta.offset, meta.offset + load_count);
 | 
					        const slice = meta.filtered_list.slice(meta.offset, meta.offset + load_count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const finish = blueslip.start_timing("list_render " + opts.name);
 | 
					        const finish = blueslip.start_timing("ListWidget " + opts.name);
 | 
				
			||||||
        let html = "";
 | 
					        let html = "";
 | 
				
			||||||
        for (const item of slice) {
 | 
					        for (const item of slice) {
 | 
				
			||||||
            const s = opts.modifier(item);
 | 
					            const s = opts.modifier(item);
 | 
				
			||||||
@@ -390,4 +389,4 @@ exports.handle_sort = function (th, list) {
 | 
				
			|||||||
    list.sort(sort_type, prop_name);
 | 
					    list.sort(sort_type, prop_name);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
window.list_render = exports;
 | 
					window.ListWidget = exports;
 | 
				
			||||||
@@ -77,7 +77,7 @@ exports.set_up_muted_topics_ui = function () {
 | 
				
			|||||||
    const muted_topics_table = $("#muted_topics_table");
 | 
					    const muted_topics_table = $("#muted_topics_table");
 | 
				
			||||||
    const $search_input = $("#muted_topics_search");
 | 
					    const $search_input = $("#muted_topics_search");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    list_render.create(muted_topics_table, muted_topics, {
 | 
					    ListWidget.create(muted_topics_table, muted_topics, {
 | 
				
			||||||
        name: "muted-topics-list",
 | 
					        name: "muted-topics-list",
 | 
				
			||||||
        modifier(muted_topics) {
 | 
					        modifier(muted_topics) {
 | 
				
			||||||
            return render_muted_topic_ui_row({muted_topics});
 | 
					            return render_muted_topic_ui_row({muted_topics});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -410,7 +410,7 @@ exports.complete_rerender = function () {
 | 
				
			|||||||
    container.empty();
 | 
					    container.empty();
 | 
				
			||||||
    const mapped_topic_values = Array.from(exports.get().values()).map((value) => value);
 | 
					    const mapped_topic_values = Array.from(exports.get().values()).map((value) => value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    topics_widget = list_render.create(container, mapped_topic_values, {
 | 
					    topics_widget = ListWidget.create(container, mapped_topic_values, {
 | 
				
			||||||
        name: "recent_topics_table",
 | 
					        name: "recent_topics_table",
 | 
				
			||||||
        parent_container: $("#recent_topics_table"),
 | 
					        parent_container: $("#recent_topics_table"),
 | 
				
			||||||
        modifier(item) {
 | 
					        modifier(item) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -83,7 +83,7 @@ exports.populate_emoji = function () {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const emoji_table = $("#admin_emoji_table").expectOne();
 | 
					    const emoji_table = $("#admin_emoji_table").expectOne();
 | 
				
			||||||
    list_render.create(emoji_table, Object.values(emoji_data), {
 | 
					    ListWidget.create(emoji_table, Object.values(emoji_data), {
 | 
				
			||||||
        name: "emoji_list",
 | 
					        name: "emoji_list",
 | 
				
			||||||
        modifier(item) {
 | 
					        modifier(item) {
 | 
				
			||||||
            if (item.deactivated !== true) {
 | 
					            if (item.deactivated !== true) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,7 +31,7 @@ exports.populate_exports_table = function (exports) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const exports_table = $("#admin_exports_table").expectOne();
 | 
					    const exports_table = $("#admin_exports_table").expectOne();
 | 
				
			||||||
    list_render.create(exports_table, Object.values(exports), {
 | 
					    ListWidget.create(exports_table, Object.values(exports), {
 | 
				
			||||||
        name: "admin_exports_list",
 | 
					        name: "admin_exports_list",
 | 
				
			||||||
        modifier(data) {
 | 
					        modifier(data) {
 | 
				
			||||||
            let failed_timestamp = data.failed_timestamp;
 | 
					            let failed_timestamp = data.failed_timestamp;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,7 +45,7 @@ function populate_invites(invites_data) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const invites_table = $("#admin_invites_table").expectOne();
 | 
					    const invites_table = $("#admin_invites_table").expectOne();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    list_render.create(invites_table, invites_data.invites, {
 | 
					    ListWidget.create(invites_table, invites_data.invites, {
 | 
				
			||||||
        name: "admin_invites_list",
 | 
					        name: "admin_invites_list",
 | 
				
			||||||
        modifier(item) {
 | 
					        modifier(item) {
 | 
				
			||||||
            item.invited_absolute_time = timerender.absolute_time(item.invited * 1000);
 | 
					            item.invited_absolute_time = timerender.absolute_time(item.invited * 1000);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,7 @@ exports.populate_filters = function (filters_data) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const filters_table = $("#admin_filters_table").expectOne();
 | 
					    const filters_table = $("#admin_filters_table").expectOne();
 | 
				
			||||||
    list_render.create(filters_table, filters_data, {
 | 
					    ListWidget.create(filters_table, filters_data, {
 | 
				
			||||||
        name: "linkifiers_list",
 | 
					        name: "linkifiers_list",
 | 
				
			||||||
        modifier(filter) {
 | 
					        modifier(filter) {
 | 
				
			||||||
            return render_admin_filter_list({
 | 
					            return render_admin_filter_list({
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,7 +26,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_id) => stream_data.get_sub_by_id(stream_id));
 | 
					    const subs = stream_ids.map((stream_id) => stream_data.get_sub_by_id(stream_id));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    list_render.create(table, subs, {
 | 
					    ListWidget.create(table, subs, {
 | 
				
			||||||
        name: "default_streams_list",
 | 
					        name: "default_streams_list",
 | 
				
			||||||
        modifier(item) {
 | 
					        modifier(item) {
 | 
				
			||||||
            return render_admin_default_streams_list({
 | 
					            return render_admin_default_streams_list({
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -254,7 +254,7 @@ section.bots.create_table = () => {
 | 
				
			|||||||
    $bots_table.hide();
 | 
					    $bots_table.hide();
 | 
				
			||||||
    const bot_user_ids = bot_data.all_user_ids();
 | 
					    const bot_user_ids = bot_data.all_user_ids();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bot_list_widget = list_render.create($bots_table, bot_user_ids, {
 | 
					    bot_list_widget = ListWidget.create($bots_table, bot_user_ids, {
 | 
				
			||||||
        name: "admin_bot_list",
 | 
					        name: "admin_bot_list",
 | 
				
			||||||
        get_item: bot_info,
 | 
					        get_item: bot_info,
 | 
				
			||||||
        modifier: render_admin_user_list,
 | 
					        modifier: render_admin_user_list,
 | 
				
			||||||
@@ -287,7 +287,7 @@ section.bots.create_table = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
section.active.create_table = (active_users) => {
 | 
					section.active.create_table = (active_users) => {
 | 
				
			||||||
    const $users_table = $("#admin_users_table");
 | 
					    const $users_table = $("#admin_users_table");
 | 
				
			||||||
    list_render.create($users_table, active_users, {
 | 
					    ListWidget.create($users_table, active_users, {
 | 
				
			||||||
        name: "users_table_list",
 | 
					        name: "users_table_list",
 | 
				
			||||||
        get_item: people.get_by_user_id,
 | 
					        get_item: people.get_by_user_id,
 | 
				
			||||||
        modifier(item) {
 | 
					        modifier(item) {
 | 
				
			||||||
@@ -315,7 +315,7 @@ section.active.create_table = (active_users) => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
section.deactivated.create_table = (deactivated_users) => {
 | 
					section.deactivated.create_table = (deactivated_users) => {
 | 
				
			||||||
    const $deactivated_users_table = $("#admin_deactivated_users_table");
 | 
					    const $deactivated_users_table = $("#admin_deactivated_users_table");
 | 
				
			||||||
    list_render.create($deactivated_users_table, deactivated_users, {
 | 
					    ListWidget.create($deactivated_users_table, deactivated_users, {
 | 
				
			||||||
        name: "deactivated_users_table_list",
 | 
					        name: "deactivated_users_table_list",
 | 
				
			||||||
        get_item: people.get_by_user_id,
 | 
					        get_item: people.get_by_user_id,
 | 
				
			||||||
        modifier(item) {
 | 
					        modifier(item) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -339,7 +339,7 @@ function show_subscription_settings(sub) {
 | 
				
			|||||||
        return user_pill.filter_taken_users(potential_subscribers, exports.pill_widget);
 | 
					        return user_pill.filter_taken_users(potential_subscribers, exports.pill_widget);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    list_render.create(list, users, {
 | 
					    ListWidget.create(list, users, {
 | 
				
			||||||
        name: "stream_subscribers/" + stream_id,
 | 
					        name: "stream_subscribers/" + stream_id,
 | 
				
			||||||
        modifier(item) {
 | 
					        modifier(item) {
 | 
				
			||||||
            return format_member_list_elem(item);
 | 
					            return format_member_list_elem(item);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -201,12 +201,12 @@ exports.update_subscribers_list = function (sub) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        /*
 | 
					        /*
 | 
				
			||||||
            We try to find a subscribers list that is already in the
 | 
					            We try to find a subscribers list that is already in the
 | 
				
			||||||
            cache that list_render.js maintains.  The list we are
 | 
					            cache that list_widget.js maintains.  The list we are
 | 
				
			||||||
            looking for would have been created in the function
 | 
					            looking for would have been created in the function
 | 
				
			||||||
            stream_edit.show_subscription_settings, using the same
 | 
					            stream_edit.show_subscription_settings, using the same
 | 
				
			||||||
            naming scheme as below for the `name` parameter.
 | 
					            naming scheme as below for the `name` parameter.
 | 
				
			||||||
        */
 | 
					        */
 | 
				
			||||||
        const subscribers_list = list_render.get("stream_subscribers/" + sub.stream_id);
 | 
					        const subscribers_list = ListWidget.get("stream_subscribers/" + sub.stream_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Changing the data clears the rendered list and the list needs to be re-rendered.
 | 
					        // Changing the data clears the rendered list and the list needs to be re-rendered.
 | 
				
			||||||
        // Perform re-rendering only when the stream settings form of the corresponding
 | 
					        // Perform re-rendering only when the stream settings form of the corresponding
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
<div id="muted-topic-settings" class="settings-section" data-name="muted-topics">
 | 
					<div id="muted-topic-settings" class="settings-section" data-name="muted-topics">
 | 
				
			||||||
    <input id="muted_topics_search" class="search" type="text" placeholder="{{t 'Search muted topics...' }}" aria-label="{{t 'Search muted topics...' }}"/>
 | 
					    <input id="muted_topics_search" class="search" type="text" placeholder="{{t 'Search muted topics...' }}" aria-label="{{t 'Search muted topics...' }}"/>
 | 
				
			||||||
    <div class="progressive-table-wrapper" data-simplebar data-list-render="muted-topics-list">
 | 
					    <div class="progressive-table-wrapper" data-simplebar data-list-widget="muted-topics-list">
 | 
				
			||||||
        <table class="table table-condensed table-striped wrapped-table">
 | 
					        <table class="table table-condensed table-striped wrapped-table">
 | 
				
			||||||
            <thead>
 | 
					            <thead>
 | 
				
			||||||
                <th data-sort="alphabetic" data-sort-prop="stream">{{t "Stream" }}</th>
 | 
					                <th data-sort="alphabetic" data-sort-prop="stream">{{t "Stream" }}</th>
 | 
				
			||||||
@@ -8,7 +8,7 @@
 | 
				
			|||||||
                <th data-sort="numeric" data-sort-prop="date_muted">{{t "Date muted" }}</th>
 | 
					                <th data-sort="numeric" data-sort-prop="date_muted">{{t "Date muted" }}</th>
 | 
				
			||||||
                <th class="actions">{{t "Actions" }}</th>
 | 
					                <th class="actions">{{t "Actions" }}</th>
 | 
				
			||||||
            </thead>
 | 
					            </thead>
 | 
				
			||||||
            <tbody id="muted_topics_table" data-empty="{{t 'You have not muted any topics yet.'}}" data-list-render="muted-topics-list"></tbody>
 | 
					            <tbody id="muted_topics_table" data-empty="{{t 'You have not muted any topics yet.'}}" data-list-widget="muted-topics-list"></tbody>
 | 
				
			||||||
        </table>
 | 
					        </table>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user