diff --git a/.eslintrc.json b/.eslintrc.json index 4d2070f073..b87140cbbe 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -42,6 +42,7 @@ "settings_emoji": false, "settings_org": false, "settings_users": false, + "settings_streams": false, "settings": false, "resize": false, "loading": false, diff --git a/frontend_tests/node_tests/dispatch.js b/frontend_tests/node_tests/dispatch.js index 9b95d9df30..4bb1facb60 100644 --- a/frontend_tests/node_tests/dispatch.js +++ b/frontend_tests/node_tests/dispatch.js @@ -412,7 +412,7 @@ with_overrides(function () { with_overrides(function (override) { // default_streams var event = event_fixtures.default_streams; - override('admin.update_default_streams_table', noop); + override('settings_streams.update_default_streams_table', noop); dispatch(event); assert_same(page_params.realm_default_streams, event.default_streams); @@ -634,7 +634,7 @@ with_overrides(function (override) { global.with_stub(function (stub) { override('stream_events.update_property', stub.f); - override('admin.update_default_streams_table', noop); + override('settings_streams.update_default_streams_table', noop); dispatch(event); var args = stub.get_args('stream_id', 'property', 'value'); assert_same(args.stream_id, event.stream_id); diff --git a/static/js/admin.js b/static/js/admin.js index 0ddee4d8d3..52fd62a2a9 100644 --- a/static/js/admin.js +++ b/static/js/admin.js @@ -4,7 +4,6 @@ var meta = { loaded: false, }; var exports = {}; -var all_streams = []; exports.show_or_hide_menu_item = function () { var item = $('.admin-menu-item').expectOne(); @@ -17,121 +16,6 @@ exports.show_or_hide_menu_item = function () { } }; -function failed_listing_streams(xhr) { - ui_report.error(i18n.t("Error listing streams"), xhr, $("#organization-status")); -} - -function populate_streams(streams_data) { - var streams_table = $("#admin_streams_table").expectOne(); - all_streams = streams_data; - streams_table.find("tr.stream_row").remove(); - _.each(streams_data.streams, function (stream) { - streams_table.append(templates.render("admin_streams_list", {stream: stream})); - }); - loading.destroy_indicator($('#admin_page_streams_loading_indicator')); -} - -exports.build_default_stream_table = function (streams_data) { - var self = {}; - - self.row_dict = new Dict(); - - function set_up_remove_click_hander(row, stream_name) { - row.on("click", ".remove-default-stream", function (e) { - e.preventDefault(); - e.stopPropagation(); - - channel.del({ - url: '/json/default_streams'+ '?' + $.param({stream_name: stream_name}), - error: function (xhr) { - var button = row.find("button"); - if (xhr.status.toString().charAt(0) === "4") { - button.closest("td").html( - $("
").addClass("text-error").text(JSON.parse(xhr.responseText).msg) - ); - } else { - button.text(i18n.t("Failed!")); - } - }, - success: function () { - row.remove(); - }, - }); - }); - } - - (function () { - var table = $("#admin_default_streams_table").expectOne(); - _.each(streams_data, function (stream) { - var row = $(templates.render("admin_default_streams_list", {stream: stream})); - set_up_remove_click_hander(row, stream.name); - self.row_dict.set(stream.stream_id, row); - table.append(row); - }); - loading.destroy_indicator($('#admin_page_default_streams_loading_indicator')); - }()); - - self.remove = function (stream_id) { - if (self.row_dict.has(stream_id)) { - var row = self.row_dict.get(stream_id); - row.remove(); - } - }; - - return self; -}; -var default_stream_table; - -exports.remove_default_stream = function (stream_id) { - if (default_stream_table) { - default_stream_table.remove(stream_id); - } -}; - -function get_non_default_streams_names(streams_data) { - var non_default_streams_names = []; - var default_streams_names = []; - - _.each(page_params.realm_default_streams, function (default_stream) { - default_streams_names.push(default_stream.name); - }); - - _.each(streams_data.streams, function (stream) { - if (default_streams_names.indexOf(stream.name) < 0) { - non_default_streams_names.push(stream.name); - } - }); - return non_default_streams_names; -} - -exports.update_default_streams_table = function () { - if (/#*organization/.test(window.location.hash) || - /#*settings/.test(window.location.hash)) { - $("#admin_default_streams_table").expectOne().find("tr.default_stream_row").remove(); - default_stream_table = exports.build_default_stream_table( - page_params.realm_default_streams); - } -}; - -function make_stream_default(stream_name) { - var data = { - stream_name: stream_name, - }; - - channel.post({ - url: '/json/default_streams', - data: data, - error: function (xhr) { - if (xhr.status.toString().charAt(0) === "4") { - $(".active_stream_row button").closest("td").html( - $("
").addClass("text-error").text(JSON.parse(xhr.responseText).msg)); - } else { - $(".active_stream_row button").text(i18n.t("Failed!")); - } - }, - }); -} - exports.populate_filters = function (filters_data) { if (!meta.loaded) { return; @@ -206,18 +90,8 @@ function _setup_page() { $("#id_realm_default_language").val(page_params.realm_default_language); // create loading indicators - loading.make_indicator($('#admin_page_streams_loading_indicator')); loading.make_indicator($('#admin_page_filters_loading_indicator')); - // Populate streams table - channel.get({ - url: '/json/streams?include_public=true&include_subscribed=true&include_default=true', - timeout: 10*1000, - idempotent: true, - success: populate_streams, - error: failed_listing_streams, - }); - // We set this flag before we're fully loaded so that the populate // methods don't short-circuit. meta.loaded = true; @@ -225,73 +99,11 @@ function _setup_page() { settings_org.set_up(); settings_emoji.set_up(); settings_users.set_up(); - - exports.update_default_streams_table(); + settings_streams.set_up(); // Populate filters table exports.populate_filters(page_params.realm_filters); - $(".admin_stream_table").on("click", ".deactivate", function (e) { - e.preventDefault(); - e.stopPropagation(); - - $(".active_stream_row").removeClass("active_stream_row"); - var row = $(e.target).closest(".stream_row"); - row.addClass("active_stream_row"); - - var stream_name = row.find('.stream_name').text(); - - $("#deactivation_stream_modal .stream_name").text(stream_name); - $("#deactivation_stream_modal").modal("show"); - }); - - $('.create_default_stream').keypress(function (e) { - if (e.which === 13) { - e.preventDefault(); - e.stopPropagation(); - } - }); - - $('.create_default_stream').typeahead({ - items: 5, - fixed: true, - source: function () { - return get_non_default_streams_names(all_streams); - }, - highlight: true, - updater: function (stream_name) { - make_stream_default(stream_name); - }, - }); - - $("#do_deactivate_stream_button").click(function () { - if ($("#deactivation_stream_modal .stream_name").text() !== $(".active_stream_row").find('.stream_name').text()) { - blueslip.error("Stream deactivation canceled due to non-matching fields."); - ui_report.message("Deactivation encountered an error. Please reload and try again.", - $("#home-error"), 'alert-error'); - } - $("#deactivation_stream_modal").modal("hide"); - $(".active_stream_row button").prop("disabled", true).text(i18n.t("Working…")); - var stream_name = $(".active_stream_row").find('.stream_name').text(); - var stream_id = stream_data.get_sub(stream_name).stream_id; - channel.del({ - url: '/json/streams/' + stream_id, - error: function (xhr) { - if (xhr.status.toString().charAt(0) === "4") { - $(".active_stream_row button").closest("td").html( - $("
").addClass("text-error").text(JSON.parse(xhr.responseText).msg) - ); - } else { - $(".active_stream_row button").text(i18n.t("Failed!")); - } - }, - success: function () { - var row = $(".active_stream_row"); - row.remove(); - }, - }); - }); - $('.admin_filters_table').on('click', '.delete', function (e) { e.preventDefault(); e.stopPropagation(); diff --git a/static/js/server_events.js b/static/js/server_events.js index 213db8d827..7d8232294b 100644 --- a/static/js/server_events.js +++ b/static/js/server_events.js @@ -20,7 +20,7 @@ function dispatch_normal_event(event) { case 'default_streams': page_params.realm_default_streams = event.default_streams; - admin.update_default_streams_table(); + settings_streams.update_default_streams_table(); break; case 'hotspots': @@ -181,7 +181,7 @@ function dispatch_normal_event(event) { event.property, event.value ); - admin.update_default_streams_table(); + settings_streams.update_default_streams_table(); } else if (event.op === 'create') { stream_data.create_streams(event.streams); } else if (event.op === 'delete') { @@ -191,7 +191,7 @@ function dispatch_normal_event(event) { } subs.remove_stream(stream.stream_id); stream_data.delete_sub(stream.stream_id); - admin.remove_default_stream(stream.stream_id); + settings_streams.remove_default_stream(stream.stream_id); stream_data.remove_default_stream(stream.stream_id); }); } diff --git a/static/js/settings_streams.js b/static/js/settings_streams.js new file mode 100644 index 0000000000..a0e71c4e65 --- /dev/null +++ b/static/js/settings_streams.js @@ -0,0 +1,215 @@ +var settings_streams = (function () { + +var exports = {}; + +var meta = { + loaded: false, +}; + +var all_streams = []; + +function failed_listing_streams(xhr) { + ui_report.error(i18n.t("Error listing streams"), xhr, $("#organization-status")); +} + +function populate_streams(streams_data) { + var streams_table = $("#admin_streams_table").expectOne(); + all_streams = streams_data; + streams_table.find("tr.stream_row").remove(); + _.each(streams_data.streams, function (stream) { + streams_table.append(templates.render("admin_streams_list", {stream: stream})); + }); + loading.destroy_indicator($('#admin_page_streams_loading_indicator')); +} + +exports.build_default_stream_table = function (streams_data) { + var self = {}; + + self.row_dict = new Dict(); + + function set_up_remove_click_hander(row, stream_name) { + row.on("click", ".remove-default-stream", function (e) { + e.preventDefault(); + e.stopPropagation(); + + channel.del({ + url: '/json/default_streams'+ '?' + $.param({stream_name: stream_name}), + error: function (xhr) { + var button = row.find("button"); + if (xhr.status.toString().charAt(0) === "4") { + button.closest("td").html( + $("
").addClass("text-error").text(JSON.parse(xhr.responseText).msg) + ); + } else { + button.text(i18n.t("Failed!")); + } + }, + success: function () { + row.remove(); + }, + }); + }); + } + + (function () { + var table = $("#admin_default_streams_table").expectOne(); + _.each(streams_data, function (stream) { + var row = $(templates.render("admin_default_streams_list", {stream: stream})); + set_up_remove_click_hander(row, stream.name); + self.row_dict.set(stream.stream_id, row); + table.append(row); + }); + loading.destroy_indicator($('#admin_page_default_streams_loading_indicator')); + }()); + + self.remove = function (stream_id) { + if (self.row_dict.has(stream_id)) { + var row = self.row_dict.get(stream_id); + row.remove(); + } + }; + + return self; +}; + +var default_stream_table; + +exports.remove_default_stream = function (stream_id) { + if (default_stream_table) { + default_stream_table.remove(stream_id); + } +}; + +function get_non_default_streams_names(streams_data) { + var non_default_streams_names = []; + var default_streams_names = []; + + _.each(page_params.realm_default_streams, function (default_stream) { + default_streams_names.push(default_stream.name); + }); + + _.each(streams_data.streams, function (stream) { + if (default_streams_names.indexOf(stream.name) < 0) { + non_default_streams_names.push(stream.name); + } + }); + return non_default_streams_names; +} + +exports.update_default_streams_table = function () { + if (/#*organization/.test(window.location.hash) || + /#*settings/.test(window.location.hash)) { + $("#admin_default_streams_table").expectOne().find("tr.default_stream_row").remove(); + default_stream_table = exports.build_default_stream_table( + page_params.realm_default_streams); + } +}; + +function make_stream_default(stream_name) { + var data = { + stream_name: stream_name, + }; + + channel.post({ + url: '/json/default_streams', + data: data, + error: function (xhr) { + if (xhr.status.toString().charAt(0) === "4") { + $(".active_stream_row button").closest("td").html( + $("
").addClass("text-error").text(JSON.parse(xhr.responseText).msg)); + } else { + $(".active_stream_row button").text(i18n.t("Failed!")); + } + }, + }); +} + +exports.set_up = function () { + loading.make_indicator($('#admin_page_streams_loading_indicator')); + + // Populate streams table + channel.get({ + url: '/json/streams?include_public=true&include_subscribed=true&include_default=true', + timeout: 10*1000, + idempotent: true, + success: exports.on_load_success, + error: failed_listing_streams, + }); +}; + +exports.on_load_success = function (streams_data) { + meta.loaded = true; + + populate_streams(streams_data); + + exports.update_default_streams_table(); + + $(".admin_stream_table").on("click", ".deactivate", function (e) { + e.preventDefault(); + e.stopPropagation(); + + $(".active_stream_row").removeClass("active_stream_row"); + var row = $(e.target).closest(".stream_row"); + row.addClass("active_stream_row"); + + var stream_name = row.find('.stream_name').text(); + + $("#deactivation_stream_modal .stream_name").text(stream_name); + $("#deactivation_stream_modal").modal("show"); + }); + + $('.create_default_stream').keypress(function (e) { + if (e.which === 13) { + e.preventDefault(); + e.stopPropagation(); + } + }); + + $('.create_default_stream').typeahead({ + items: 5, + fixed: true, + source: function () { + return get_non_default_streams_names(all_streams); + }, + highlight: true, + updater: function (stream_name) { + make_stream_default(stream_name); + }, + }); + + $("#do_deactivate_stream_button").click(function () { + if ($("#deactivation_stream_modal .stream_name").text() !== $(".active_stream_row").find('.stream_name').text()) { + blueslip.error("Stream deactivation canceled due to non-matching fields."); + ui_report.message("Deactivation encountered an error. Please reload and try again.", + $("#home-error"), 'alert-error'); + } + $("#deactivation_stream_modal").modal("hide"); + $(".active_stream_row button").prop("disabled", true).text(i18n.t("Working…")); + var stream_name = $(".active_stream_row").find('.stream_name').text(); + var stream_id = stream_data.get_sub(stream_name).stream_id; + channel.del({ + url: '/json/streams/' + stream_id, + error: function (xhr) { + if (xhr.status.toString().charAt(0) === "4") { + $(".active_stream_row button").closest("td").html( + $("
").addClass("text-error").text(JSON.parse(xhr.responseText).msg) + ); + } else { + $(".active_stream_row button").text(i18n.t("Failed!")); + } + }, + success: function () { + var row = $(".active_stream_row"); + row.remove(); + }, + }); + }); + +}; + +return exports; +}()); + +if (typeof module !== 'undefined') { + module.exports = settings_streams; +} diff --git a/zproject/settings.py b/zproject/settings.py index d58419ecfb..da156e477f 100644 --- a/zproject/settings.py +++ b/zproject/settings.py @@ -916,6 +916,7 @@ JS_SPECS = { 'js/settings_emoji.js', 'js/settings_org.js', 'js/settings_users.js', + 'js/settings_streams.js', 'js/settings.js', 'js/admin.js', 'js/tab_bar.js',