mirror of https://github.com/zulip/zulip.git
streams: Allow creating stream pills to submit Add subscriber form.
We update the pills typeahead logic to also include stream results and pass the "stream" key in `opts` to enable this option for the Add subscriber form. This commit implements the feature of adding all the subscribers of another stream in the "Add subscribers" UI, with the help of a new "stream_pill.js` file. We temporarily add `user_pill.js` to the EXEMPT_FILES list as typeahead will be set up in `stream_edit.js` file which does not have any dedicated tests file. Work towards #15186.
This commit is contained in:
parent
b93371aa9f
commit
c6d9a87d6f
|
@ -249,6 +249,7 @@
|
|||
"stream_topic_history": false,
|
||||
"stream_list": false,
|
||||
"stream_muting": false,
|
||||
"stream_pill": false,
|
||||
"stream_popover": false,
|
||||
"stream_sort": false,
|
||||
"stream_ui_updates": false,
|
||||
|
|
|
@ -32,6 +32,7 @@ import "../localstorage.js";
|
|||
import "../drafts.js";
|
||||
import "../input_pill.js";
|
||||
import "../user_pill.js";
|
||||
import "../stream_pill.js";
|
||||
import "../compose_pm_pill.js";
|
||||
import "../channel.js";
|
||||
import "../setup.js";
|
||||
|
|
|
@ -145,6 +145,7 @@ declare let stream_edit: any;
|
|||
declare let stream_events: any;
|
||||
declare let stream_list: any;
|
||||
declare let stream_muting: any;
|
||||
declare let stream_pill: any;
|
||||
declare let stream_popover: any;
|
||||
declare let stream_sort: any;
|
||||
declare let stream_ui_updates: any;
|
||||
|
|
|
@ -7,18 +7,35 @@ exports.set_up = function (input, pills, opts) {
|
|||
if (!opts.source) {
|
||||
source = () => user_pill.typeahead_source(pills);
|
||||
}
|
||||
const include_streams = (query) => opts.stream && query.trim().startsWith("#");
|
||||
|
||||
input.typeahead({
|
||||
items: 5,
|
||||
fixed: true,
|
||||
dropup: true,
|
||||
source,
|
||||
source() {
|
||||
if (include_streams(this.query)) {
|
||||
return stream_pill.typeahead_source(pills);
|
||||
}
|
||||
|
||||
return source();
|
||||
},
|
||||
highlighter(item) {
|
||||
if (include_streams(this.query)) {
|
||||
return typeahead_helper.render_stream(item);
|
||||
}
|
||||
|
||||
return typeahead_helper.render_person(item);
|
||||
},
|
||||
matcher(item) {
|
||||
let query = this.query.toLowerCase();
|
||||
query = query.replace(/\u00A0/g, String.fromCharCode(32));
|
||||
|
||||
if (include_streams(query)) {
|
||||
query = query.trim().substring(1);
|
||||
return item.name.toLowerCase().indexOf(query) !== -1;
|
||||
}
|
||||
|
||||
if (!settings_data.show_email()) {
|
||||
return item.full_name.toLowerCase().includes(query);
|
||||
}
|
||||
|
@ -28,10 +45,19 @@ exports.set_up = function (input, pills, opts) {
|
|||
);
|
||||
},
|
||||
sorter(matches) {
|
||||
if (include_streams(this.query)) {
|
||||
return typeahead_helper.sort_streams(matches, this.query.trim().substring(1));
|
||||
}
|
||||
|
||||
return typeahead_helper.sort_recipientbox_typeahead(this.query, matches, "");
|
||||
},
|
||||
updater(user) {
|
||||
user_pill.append_user(user, pills);
|
||||
updater(item) {
|
||||
if (include_streams(this.query)) {
|
||||
stream_pill.append_stream(item, pills);
|
||||
} else {
|
||||
user_pill.append_user(item, pills);
|
||||
}
|
||||
|
||||
input.trigger("focus");
|
||||
if (opts.update_func) {
|
||||
opts.update_func();
|
||||
|
|
|
@ -203,16 +203,25 @@ function submit_add_subscriber_form(e) {
|
|||
return;
|
||||
}
|
||||
|
||||
const user_ids = user_pill.get_user_ids(exports.pill_widget);
|
||||
const stream_subscription_info_elem = $(".stream_subscription_info").expectOne();
|
||||
let user_ids = user_pill.get_user_ids(exports.pill_widget);
|
||||
user_ids = user_ids.concat(stream_pill.get_user_ids(exports.pill_widget));
|
||||
user_ids = new Set(user_ids);
|
||||
|
||||
if (user_ids.length === 0) {
|
||||
if (user_ids.has(page_params.user_id) && sub.subscribed) {
|
||||
// We don't want to send a request to subscribe ourselves
|
||||
// if we are already subscribed to this stream. This
|
||||
// case occurs when creating user pills from a stream.
|
||||
user_ids.delete(page_params.user_id);
|
||||
}
|
||||
if (user_ids.size === 0) {
|
||||
stream_subscription_info_elem
|
||||
.text(i18n.t("No user to subscribe."))
|
||||
.addClass("text-error")
|
||||
.removeClass("text-success");
|
||||
return;
|
||||
}
|
||||
user_ids = Array.from(user_ids);
|
||||
|
||||
function invite_success(data) {
|
||||
exports.pill_widget.clear();
|
||||
|
@ -337,7 +346,7 @@ function show_subscription_settings(sub) {
|
|||
simplebar_container: $(".subscriber_list_container"),
|
||||
});
|
||||
|
||||
const opts = {source: get_users_for_subscriber_typeahead};
|
||||
const opts = {source: get_users_for_subscriber_typeahead, stream: true};
|
||||
pill_typeahead.set_up(sub_settings.find(".input"), exports.pill_widget, opts);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
"use strict";
|
||||
|
||||
function get_user_ids_from_subs(items) {
|
||||
let user_ids = [];
|
||||
const stream_ids = items.map((item) => item.stream_id);
|
||||
for (const stream_id of stream_ids) {
|
||||
const sub = stream_data.get_sub_by_id(stream_id);
|
||||
if (!sub) {
|
||||
continue;
|
||||
}
|
||||
user_ids = user_ids.concat(sub.subscribers.map());
|
||||
}
|
||||
return user_ids;
|
||||
}
|
||||
|
||||
exports.get_user_ids = function (pill_widget) {
|
||||
const items = pill_widget.items();
|
||||
let user_ids = get_user_ids_from_subs(items);
|
||||
user_ids = Array.from(new Set(user_ids));
|
||||
|
||||
user_ids = user_ids.filter(Boolean);
|
||||
return user_ids;
|
||||
};
|
||||
|
||||
exports.append_stream = function (stream, pill_widget) {
|
||||
pill_widget.appendValidatedData({
|
||||
display_value: "#" + stream.name + ": " + stream.subscriber_count + " users",
|
||||
stream_id: stream.stream_id,
|
||||
});
|
||||
pill_widget.clear_text();
|
||||
};
|
||||
|
||||
exports.get_stream_ids = function (pill_widget) {
|
||||
const items = pill_widget.items();
|
||||
let stream_ids = items.map((item) => item.stream_id);
|
||||
stream_ids = stream_ids.filter(Boolean);
|
||||
|
||||
return stream_ids;
|
||||
};
|
||||
|
||||
exports.filter_taken_streams = function (items, pill_widget) {
|
||||
const taken_stream_ids = exports.get_stream_ids(pill_widget);
|
||||
items = items.filter((item) => !taken_stream_ids.includes(item.stream_id));
|
||||
return items;
|
||||
};
|
||||
|
||||
exports.typeahead_source = function (pill_widget) {
|
||||
const potential_streams = stream_data.get_unsorted_subs();
|
||||
return exports.filter_taken_streams(potential_streams, pill_widget);
|
||||
};
|
||||
|
||||
window.stream_pill = exports;
|
|
@ -12,7 +12,7 @@
|
|||
<div class="add_subscribers_container">
|
||||
<div class="pill-container person_picker">
|
||||
<div class="input" contenteditable="true"
|
||||
data-placeholder="{{t 'Add subscribers' }}"></div>
|
||||
data-placeholder="{{t 'Add subscribers. Use #streamname to subscribe a whole stream' }}"></div>
|
||||
</div>
|
||||
<div class="add_subscriber_btn_wrapper inline-block">
|
||||
<button type="submit" name="add_subscriber" class="button add-subscriber-button small rounded" tabindex="0">
|
||||
|
|
|
@ -136,6 +136,7 @@ EXEMPT_FILES = {
|
|||
'static/js/stream_edit.js',
|
||||
'static/js/stream_list.js',
|
||||
'static/js/stream_muting.js',
|
||||
'static/js/stream_pill.js',
|
||||
'static/js/stream_popover.js',
|
||||
'static/js/stream_ui_updates.js',
|
||||
'static/js/submessage.js',
|
||||
|
@ -157,6 +158,7 @@ EXEMPT_FILES = {
|
|||
'static/js/unread_ops.js',
|
||||
'static/js/unread_ui.js',
|
||||
'static/js/upload_widget.js',
|
||||
'static/js/user_pill.js',
|
||||
'static/js/user_status_ui.js',
|
||||
'static/js/zcommand.js',
|
||||
'static/js/zform.js',
|
||||
|
|
Loading…
Reference in New Issue