mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 22:13:26 +00:00
recent_topics: Add functionality to sort rows via header.
Add custom sorting for stream and topic headers.
This commit is contained in:
@@ -74,6 +74,16 @@ set_global('list_render', {
|
|||||||
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
|
||||||
|
// are tested in list_render
|
||||||
|
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[1], mapped_topic_values[0]);
|
||||||
|
opts.sort_fields.stream_sort(mapped_topic_values[0], mapped_topic_values[0]);
|
||||||
|
opts.sort_fields.topic_sort(mapped_topic_values[0], mapped_topic_values[1]);
|
||||||
|
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]);
|
||||||
|
}
|
||||||
return list_render;
|
return list_render;
|
||||||
},
|
},
|
||||||
hard_redraw: noop,
|
hard_redraw: noop,
|
||||||
@@ -88,6 +98,7 @@ set_global('list_render', {
|
|||||||
const stream1 = 1;
|
const stream1 = 1;
|
||||||
const stream2 = 2;
|
const stream2 = 2;
|
||||||
const stream3 = 3;
|
const stream3 = 3;
|
||||||
|
const stream4 = 4;
|
||||||
|
|
||||||
// Topics in the stream, all unread except topic1 & stream1.
|
// Topics in the stream, all unread except topic1 & stream1.
|
||||||
const topic1 = "topic-1"; // No Other sender & read.
|
const topic1 = "topic-1"; // No Other sender & read.
|
||||||
@@ -99,6 +110,7 @@ const topic6 = "topic-6"; // other sender
|
|||||||
const topic7 = "topic-7"; // muted topic
|
const topic7 = "topic-7"; // muted topic
|
||||||
const topic8 = "topic-8";
|
const topic8 = "topic-8";
|
||||||
const topic9 = "topic-9";
|
const topic9 = "topic-9";
|
||||||
|
const topic10 = "topic-10";
|
||||||
|
|
||||||
set_global('muting', {
|
set_global('muting', {
|
||||||
is_topic_muted: (stream_id, topic) => {
|
is_topic_muted: (stream_id, topic) => {
|
||||||
@@ -221,6 +233,16 @@ messages[9] = {
|
|||||||
type: 'stream',
|
type: 'stream',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// a message of stream4
|
||||||
|
messages[10] = {
|
||||||
|
stream_id: stream4,
|
||||||
|
stream: 'stream4',
|
||||||
|
id: id += 1,
|
||||||
|
topic: topic10,
|
||||||
|
sender_id: sender1,
|
||||||
|
type: 'stream',
|
||||||
|
};
|
||||||
|
|
||||||
function generate_topic_data(topic_info_array) {
|
function generate_topic_data(topic_info_array) {
|
||||||
// Since most of the fields are common, this function helps generate fixtures
|
// Since most of the fields are common, this function helps generate fixtures
|
||||||
// with non common fields.
|
// with non common fields.
|
||||||
@@ -355,6 +377,7 @@ run_test('test_filter_unread', () => {
|
|||||||
|
|
||||||
const row_data = generate_topic_data([
|
const row_data = generate_topic_data([
|
||||||
// stream_id, topic, unread_count, muted, participated
|
// stream_id, topic, unread_count, muted, participated
|
||||||
|
[4, 'topic-10', 1, false, true],
|
||||||
[1, 'topic-7', 1, true, true],
|
[1, 'topic-7', 1, true, true],
|
||||||
[1, 'topic-6', 1, false, true],
|
[1, 'topic-6', 1, false, true],
|
||||||
[1, 'topic-5', 1, false, true],
|
[1, 'topic-5', 1, false, true],
|
||||||
@@ -420,6 +443,7 @@ run_test('test_filter_participated', () => {
|
|||||||
|
|
||||||
const row_data = generate_topic_data([
|
const row_data = generate_topic_data([
|
||||||
// stream_id, topic, unread_count, muted, participated
|
// stream_id, topic, unread_count, muted, participated
|
||||||
|
[4, 'topic-10', 1, false, true],
|
||||||
[1, 'topic-7', 1, true, true],
|
[1, 'topic-7', 1, true, true],
|
||||||
[1, 'topic-6', 1, false, true],
|
[1, 'topic-6', 1, false, true],
|
||||||
[1, 'topic-5', 1, false, true],
|
[1, 'topic-5', 1, false, true],
|
||||||
@@ -499,19 +523,19 @@ run_test('basic assertions', () => {
|
|||||||
generate_topic_data([[1, 'topic-7', 1, false, true]]);
|
generate_topic_data([[1, 'topic-7', 1, false, true]]);
|
||||||
rt.process_messages([messages[9]]);
|
rt.process_messages([messages[9]]);
|
||||||
// Check for expected lengths.
|
// Check for expected lengths.
|
||||||
// total 7 topics, 1 muted
|
// total 8 topics, 1 muted
|
||||||
assert.equal(all_topics.size, 7);
|
assert.equal(all_topics.size, 8);
|
||||||
assert.equal(Array.from(all_topics.keys()).toString(),
|
assert.equal(Array.from(all_topics.keys()).toString(),
|
||||||
'1:topic-7,1:topic-6,1:topic-5,1:topic-4,1:topic-3,1:topic-2,1:topic-1');
|
'4:topic-10,1:topic-7,1:topic-6,1:topic-5,1:topic-4,1:topic-3,1:topic-2,1:topic-1');
|
||||||
|
|
||||||
rt.process_message({
|
rt.process_message({
|
||||||
type: 'private',
|
type: 'private',
|
||||||
});
|
});
|
||||||
|
|
||||||
// Private msgs are not processed.
|
// Private msgs are not processed.
|
||||||
assert.equal(all_topics.size, 7);
|
assert.equal(all_topics.size, 8);
|
||||||
assert.equal(Array.from(all_topics.keys()).toString(),
|
assert.equal(Array.from(all_topics.keys()).toString(),
|
||||||
'1:topic-7,1:topic-6,1:topic-5,1:topic-4,1:topic-3,1:topic-2,1:topic-1');
|
'4:topic-10,1:topic-7,1:topic-6,1:topic-5,1:topic-4,1:topic-3,1:topic-2,1:topic-1');
|
||||||
|
|
||||||
// participated
|
// participated
|
||||||
verify_topic_data(all_topics, stream1, topic1, messages[0].id, true);
|
verify_topic_data(all_topics, stream1, topic1, messages[0].id, true);
|
||||||
@@ -533,7 +557,7 @@ run_test('basic assertions', () => {
|
|||||||
|
|
||||||
all_topics = rt.get();
|
all_topics = rt.get();
|
||||||
assert.equal(Array.from(all_topics.keys()).toString(),
|
assert.equal(Array.from(all_topics.keys()).toString(),
|
||||||
'1:topic-3,1:topic-7,1:topic-6,1:topic-5,1:topic-4,1:topic-2,1:topic-1');
|
'1:topic-3,4:topic-10,1:topic-7,1:topic-6,1:topic-5,1:topic-4,1:topic-2,1:topic-1');
|
||||||
verify_topic_data(all_topics, stream1, topic3, id, true);
|
verify_topic_data(all_topics, stream1, topic3, id, true);
|
||||||
|
|
||||||
// Send new message to topic7 (muted)
|
// Send new message to topic7 (muted)
|
||||||
@@ -548,7 +572,7 @@ run_test('basic assertions', () => {
|
|||||||
|
|
||||||
all_topics = rt.get();
|
all_topics = rt.get();
|
||||||
assert.equal(Array.from(all_topics.keys()).toString(),
|
assert.equal(Array.from(all_topics.keys()).toString(),
|
||||||
'1:topic-7,1:topic-3,1:topic-6,1:topic-5,1:topic-4,1:topic-2,1:topic-1');
|
'1:topic-7,1:topic-3,4:topic-10,1:topic-6,1:topic-5,1:topic-4,1:topic-2,1:topic-1');
|
||||||
|
|
||||||
// update_topic_is_muted now relies on external libraries completely
|
// update_topic_is_muted now relies on external libraries completely
|
||||||
// so we don't need to check anythere here.
|
// so we don't need to check anythere here.
|
||||||
@@ -607,7 +631,7 @@ run_test('test_topic_edit', () => {
|
|||||||
|
|
||||||
let all_topics = rt.get();
|
let all_topics = rt.get();
|
||||||
assert.equal(Array.from(all_topics.keys()).toString(),
|
assert.equal(Array.from(all_topics.keys()).toString(),
|
||||||
'1:topic-7,1:topic-6,1:topic-5,1:topic-4,1:topic-3,1:topic-2,1:topic-1');
|
'4:topic-10,1:topic-7,1:topic-6,1:topic-5,1:topic-4,1:topic-3,1:topic-2,1:topic-1');
|
||||||
|
|
||||||
////////////////// test change topic //////////////////
|
////////////////// test change topic //////////////////
|
||||||
verify_topic_data(all_topics, stream1, topic6, messages[8].id, true);
|
verify_topic_data(all_topics, stream1, topic6, messages[8].id, true);
|
||||||
|
|||||||
@@ -249,6 +249,29 @@ exports.update_filters_view = function () {
|
|||||||
topics_widget.hard_redraw();
|
topics_widget.hard_redraw();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function stream_sort(a, b) {
|
||||||
|
const a_stream = message_store.get(a.last_msg_id).stream;
|
||||||
|
const b_stream = message_store.get(b.last_msg_id).stream;
|
||||||
|
if (a_stream > b_stream) {
|
||||||
|
return 1;
|
||||||
|
} else if (a_stream === b_stream) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function topic_sort(a, b) {
|
||||||
|
const a_topic = message_store.get(a.last_msg_id).topic;
|
||||||
|
const b_topic = message_store.get(b.last_msg_id).topic;
|
||||||
|
if (a_topic > b_topic) {
|
||||||
|
return 1;
|
||||||
|
} else if (a_topic === b_topic) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
exports.complete_rerender = function () {
|
exports.complete_rerender = function () {
|
||||||
if (!overlays.recent_topics_open()) {
|
if (!overlays.recent_topics_open()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -272,6 +295,7 @@ exports.complete_rerender = function () {
|
|||||||
|
|
||||||
topics_widget = list_render.create(container, mapped_topic_values, {
|
topics_widget = list_render.create(container, mapped_topic_values, {
|
||||||
name: "recent_topics_table",
|
name: "recent_topics_table",
|
||||||
|
parent_container: $("#recent_topics_table"),
|
||||||
modifier: function (item) {
|
modifier: function (item) {
|
||||||
return render_recent_topic_row(format_topic(item));
|
return render_recent_topic_row(format_topic(item));
|
||||||
},
|
},
|
||||||
@@ -282,6 +306,10 @@ exports.complete_rerender = function () {
|
|||||||
return !is_topic_hidden(topic_data);
|
return !is_topic_hidden(topic_data);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
sort_fields: {
|
||||||
|
stream_sort: stream_sort,
|
||||||
|
topic_sort: topic_sort,
|
||||||
|
},
|
||||||
html_selector: get_topic_row,
|
html_selector: get_topic_row,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -76,8 +76,6 @@
|
|||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
background-color: hsl(0, 0%, 27%);
|
|
||||||
color: hsl(0, 0%, 100%);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#recent_topics_filter_buttons {
|
#recent_topics_filter_buttons {
|
||||||
@@ -151,5 +149,42 @@
|
|||||||
.recent_avatars_others {
|
.recent_avatars_others {
|
||||||
background-color: hsl(205.2, 76.5%, 50%);
|
background-color: hsl(205.2, 76.5%, 50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thead th {
|
||||||
|
background-color: inherit;
|
||||||
|
color: inherit;
|
||||||
|
border-top: 1px solid hsla(0, 0%, 0%, 0.2) !important;
|
||||||
|
border-bottom: 1px solid hsla(0, 0%, 0%, 0.2) !important;
|
||||||
|
|
||||||
|
&.active::after,
|
||||||
|
&[data-sort]:hover::after {
|
||||||
|
content: " \f0d8";
|
||||||
|
white-space: pre;
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
padding-top: 3px;
|
||||||
|
font: normal normal normal 12px/1 FontAwesome;
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 100ms ease-out;
|
||||||
|
|
||||||
|
&.descend::after {
|
||||||
|
content: " \f0d7";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-sort]:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: hsla(0, 0%, 0%, 0.05);
|
||||||
|
transition: background-color 100ms ease-in-out;
|
||||||
|
|
||||||
|
&:not(.active)::after {
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,11 @@
|
|||||||
<table class="table table-responsive table-hover">
|
<table class="table table-responsive table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{t 'Stream' }}</th>
|
<th data-sort="stream_sort">{{t 'Stream' }}</th>
|
||||||
<th>{{t 'Topic' }}</th>
|
<th data-sort="topic_sort">{{t 'Topic' }}</th>
|
||||||
<th>{{t 'Actions' }}</th>
|
<th>{{t 'Actions' }}</th>
|
||||||
<th>{{t 'Participants' }}</th>
|
<th>{{t 'Participants' }}</th>
|
||||||
<th>{{t 'Last message' }}</th>
|
<th data-sort="numeric" data-sort-prop="last_msg_id" class="active descend">{{t 'Last message' }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|||||||
Reference in New Issue
Block a user