mirror of
				https://github.com/zulip/zulip.git
				synced 2025-10-31 20:13:46 +00:00 
			
		
		
		
	redesign: Change /#settings and /#administration to an overlay.
This also adds a box-shadow to the #deactivate_self_modal so that it looks similar to the old backdrop.
This commit is contained in:
		
				
					committed by
					
						 Tim Abbott
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							7a76f3dcc8
						
					
				
				
					commit
					1143ed7219
				
			| @@ -22,9 +22,9 @@ casper.then(function () { | |||||||
| }); | }); | ||||||
|  |  | ||||||
| casper.then(function () { | casper.then(function () { | ||||||
|     casper.waitUntilVisible("#settings-change-box", function () { |     casper.waitUntilVisible("#settings_content .account-settings-form", function () { | ||||||
|         casper.test.assertUrlMatch(/^http:\/\/[^/]+\/#settings/, 'URL suggests we are on settings page'); |         casper.test.assertUrlMatch(/^http:\/\/[^/]+\/#settings/, 'URL suggests we are on settings page'); | ||||||
|         casper.test.assertExists('#settings.tab-pane.active', 'Settings page is active'); |         casper.test.assertVisible('.account-settings-form', 'Settings page is active'); | ||||||
|  |  | ||||||
|         casper.test.assertNotVisible("#pw_change_controls"); |         casper.test.assertNotVisible("#pw_change_controls"); | ||||||
|  |  | ||||||
| @@ -56,6 +56,7 @@ casper.then(function () { | |||||||
|     casper.waitUntilVisible('#settings-status', function () { |     casper.waitUntilVisible('#settings-status', function () { | ||||||
|         casper.test.assertSelectorHasText('#settings-status', 'Updated settings!'); |         casper.test.assertSelectorHasText('#settings-status', 'Updated settings!'); | ||||||
|  |  | ||||||
|  |         casper.click('[data-section="your-bots"]'); | ||||||
|         casper.click('#api_key_button'); |         casper.click('#api_key_button'); | ||||||
|     }); |     }); | ||||||
| }); | }); | ||||||
| @@ -196,6 +197,7 @@ casper.waitForSelector('#create_alert_word_form', function () { | |||||||
|  |  | ||||||
| casper.then(function change_default_language() { | casper.then(function change_default_language() { | ||||||
|     casper.test.info('Changing the default language'); |     casper.test.info('Changing the default language'); | ||||||
|  |     casper.click('[data-section="display-settings"]'); | ||||||
|     casper.waitForSelector('#default_language'); |     casper.waitForSelector('#default_language'); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| @@ -236,6 +238,7 @@ casper.waitForSelector("#settings-change-box", function check_url_preference() { | |||||||
|         return document.documentElement.lang; |         return document.documentElement.lang; | ||||||
|     }, 'de'); |     }, 'de'); | ||||||
|     casper.test.info("English is now the default language"); |     casper.test.info("English is now the default language"); | ||||||
|  |     casper.click('[data-section="display-settings"]'); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| casper.thenClick('#default_language'); | casper.thenClick('#default_language'); | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ function wait_for_tab(tab) { | |||||||
| function then_navigate_to(click_target, tab) { | function then_navigate_to(click_target, tab) { | ||||||
|     casper.then(function () { |     casper.then(function () { | ||||||
|         casper.test.info('Visiting #' + click_target); |         casper.test.info('Visiting #' + click_target); | ||||||
|         casper.click('a[href^="#' + click_target + '"]'); |         casper.click("a[href='#" + click_target + "']"); | ||||||
|         wait_for_tab(tab); |         wait_for_tab(tab); | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| @@ -30,7 +30,10 @@ function then_navigate_to_settings() { | |||||||
|             casper.click(menu_selector); |             casper.click(menu_selector); | ||||||
|             casper.waitUntilVisible('a[href^="#settings"]', function () { |             casper.waitUntilVisible('a[href^="#settings"]', function () { | ||||||
|                 casper.click('a[href^="#settings"]'); |                 casper.click('a[href^="#settings"]'); | ||||||
|                 wait_for_tab('settings'); |                 casper.waitForSelector('#settings_page', function () { | ||||||
|  |                     casper.test.assertExists('#settings_page', "Settings page is active"); | ||||||
|  |                     casper.click("#settings_page .exit"); | ||||||
|  |                 }); | ||||||
|             }); |             }); | ||||||
|         }); |         }); | ||||||
|     }); |     }); | ||||||
| @@ -53,7 +56,6 @@ function then_navigate_to_subscriptions() { | |||||||
|  |  | ||||||
| // Take a navigation tour of the app. | // Take a navigation tour of the app. | ||||||
| // Entries are (click target, tab that should be active after clicking). | // Entries are (click target, tab that should be active after clicking). | ||||||
|  |  | ||||||
| then_navigate_to_settings(); | then_navigate_to_settings(); | ||||||
| then_navigate_to('narrow/stream/Verona', 'home'); | then_navigate_to('narrow/stream/Verona', 'home'); | ||||||
| then_navigate_to('home', 'home'); | then_navigate_to('home', 'home'); | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ casper.then(function () { | |||||||
|     casper.click('a[href^="#administration"]'); |     casper.click('a[href^="#administration"]'); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| casper.waitForSelector('#administration.tab-pane.active', function () { | casper.waitForSelector('#settings_overlay_container.show', function () { | ||||||
|     casper.test.info('Administration page is active'); |     casper.test.info('Administration page is active'); | ||||||
|     casper.test.assertUrlMatch(/^http:\/\/[^/]+\/#administration/, 'URL suggests we are on administration page'); |     casper.test.assertUrlMatch(/^http:\/\/[^/]+\/#administration/, 'URL suggests we are on administration page'); | ||||||
| }); | }); | ||||||
| @@ -23,7 +23,6 @@ casper.waitForSelector('#administration.tab-pane.active', function () { | |||||||
| casper.waitForSelector('input[type="checkbox"][id="id_realm_create_stream_by_admins_only"]', function () { | casper.waitForSelector('input[type="checkbox"][id="id_realm_create_stream_by_admins_only"]', function () { | ||||||
|     casper.click('input[type="checkbox"][id="id_realm_create_stream_by_admins_only"]'); |     casper.click('input[type="checkbox"][id="id_realm_create_stream_by_admins_only"]'); | ||||||
|     casper.click('form.admin-realm-form input.button'); |     casper.click('form.admin-realm-form input.button'); | ||||||
|  |  | ||||||
| }); | }); | ||||||
|  |  | ||||||
| casper.then(function () { | casper.then(function () { | ||||||
| @@ -64,14 +63,15 @@ casper.then(function () { | |||||||
|     }); |     }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  |  | ||||||
| casper.then(function () { | casper.then(function () { | ||||||
|     // Test custom realm emoji |     // Test custom realm emoji | ||||||
|  |     casper.click("li[data-section='emoji-settings']"); | ||||||
|     casper.waitForSelector('.admin-emoji-form', function () { |     casper.waitForSelector('.admin-emoji-form', function () { | ||||||
|         casper.fill('form.admin-emoji-form', { |         casper.fill('form.admin-emoji-form', { | ||||||
|             name: 'MouseFace', |             name: 'MouseFace', | ||||||
|             url: 'http://zulipdev.com:9991/static/images/integrations/logos/jenkins.png', |             url: 'http://zulipdev.com:9991/static/images/integrations/logos/jenkins.png', | ||||||
|         }); |         }, true); | ||||||
|         casper.click('form.admin-emoji-form input.button'); |  | ||||||
|     }); |     }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| @@ -97,6 +97,7 @@ casper.then(function () { | |||||||
|  |  | ||||||
| // Test custom realm filters | // Test custom realm filters | ||||||
| casper.then(function () { | casper.then(function () { | ||||||
|  |     casper.click("li[data-section='filter-settings']"); | ||||||
|     casper.waitForSelector('.admin-filter-form', function () { |     casper.waitForSelector('.admin-filter-form', function () { | ||||||
|         casper.fill('form.admin-filter-form', { |         casper.fill('form.admin-filter-form', { | ||||||
|             pattern: '#(?P<id>[0-9]+)', |             pattern: '#(?P<id>[0-9]+)', | ||||||
| @@ -168,10 +169,7 @@ function select_from_suggestions(item) { | |||||||
|  |  | ||||||
| // Test default stream creation and addition | // Test default stream creation and addition | ||||||
| casper.then(function () { | casper.then(function () { | ||||||
|     casper.click('#settings-dropdown'); |     casper.click("li[data-section='default-streams-list']"); | ||||||
|     casper.click('a[href^="#subscriptions"]'); |  | ||||||
|     casper.click('#settings-dropdown'); |  | ||||||
|     casper.click('a[href^="#administration"]'); |  | ||||||
|     casper.waitUntilVisible(".create_default_stream", function () { |     casper.waitUntilVisible(".create_default_stream", function () { | ||||||
|         // It matches with all the stream names which has 'O' as a substring (Rome, Scotland, Verona |         // It matches with all the stream names which has 'O' as a substring (Rome, Scotland, Verona | ||||||
|         // etc). 'O' is used to make sure that it works even if there are multiple suggestions. |         // etc). 'O' is used to make sure that it works even if there are multiple suggestions. | ||||||
| @@ -201,9 +199,11 @@ casper.then(function () { | |||||||
|     }); |     }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  |  | ||||||
| // TODO: Test stream deletion | // TODO: Test stream deletion | ||||||
|  |  | ||||||
| casper.then(function () { | casper.then(function () { | ||||||
|  |     casper.click("li[data-section='organization-settings']"); | ||||||
|     casper.waitUntilVisible('#id_realm_default_language', function () { |     casper.waitUntilVisible('#id_realm_default_language', function () { | ||||||
|         casper.test.info("Changing realm default language"); |         casper.test.info("Changing realm default language"); | ||||||
|         casper.evaluate(function () { |         casper.evaluate(function () { | ||||||
| @@ -222,6 +222,7 @@ casper.then(function () { | |||||||
|  |  | ||||||
| // Test authentication methods setting | // Test authentication methods setting | ||||||
| casper.then(function () { | casper.then(function () { | ||||||
|  |     casper.click("li[data-section='auth-methods']"); | ||||||
|     casper.waitForSelector(".method_row[data-method='Email'] input[type='checkbox']", function () { |     casper.waitForSelector(".method_row[data-method='Email'] input[type='checkbox']", function () { | ||||||
|         casper.click(".method_row[data-method='Email'] input[type='checkbox']"); |         casper.click(".method_row[data-method='Email'] input[type='checkbox']"); | ||||||
|         casper.click('form.admin-realm-form input.button'); |         casper.click('form.admin-realm-form input.button'); | ||||||
|   | |||||||
| @@ -96,7 +96,7 @@ casper.then(function () { | |||||||
|  |  | ||||||
| // go back to home page | // go back to home page | ||||||
| casper.then(function () { | casper.then(function () { | ||||||
|     casper.click('.global-filter[data-name="home"]'); |     casper.click('.settings-header .exit'); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| // Commented out due to Issue #1243 | // Commented out due to Issue #1243 | ||||||
| @@ -156,7 +156,7 @@ casper.waitForSelector('input[type="checkbox"][id="id_realm_allow_message_editin | |||||||
| // Commented out due to Issue #1243 | // Commented out due to Issue #1243 | ||||||
| // go back home | // go back home | ||||||
| // casper.then(function () { | // casper.then(function () { | ||||||
| //     casper.click('.global-filter[data-name="home"]'); | //     casper.click('.settings-header .exit'); | ||||||
| // }); | // }); | ||||||
|  |  | ||||||
| // // save our edit | // // save our edit | ||||||
| @@ -192,8 +192,8 @@ casper.waitForSelector('input[type="checkbox"][id="id_realm_allow_message_editin | |||||||
| casper.then(function () { | casper.then(function () { | ||||||
|     casper.test.info('Administration page'); |     casper.test.info('Administration page'); | ||||||
|     casper.click('a[href^="#administration"]'); |     casper.click('a[href^="#administration"]'); | ||||||
|     casper.test.assertUrlMatch(/^http:\/\/[^/]+\/#administration/, 'URL suggests we are on administration page'); |     casper.test.assertUrlMatch(/^http:\/\/[^\/]+\/#administration/, 'URL suggests we are on administration page'); | ||||||
|     casper.test.assertExists('#administration.tab-pane.active', 'Administration page is active'); |     casper.test.assertExists('#settings_overlay_container.show', 'Administration page is active'); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| casper.waitForSelector('form.admin-realm-form input.button'); | casper.waitForSelector('form.admin-realm-form input.button'); | ||||||
|   | |||||||
| @@ -10,6 +10,12 @@ casper.then(function () { | |||||||
|     }); |     }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | casper.then(function () { | ||||||
|  |     casper.waitForSelector('#settings_overlay_container.show', function () { | ||||||
|  |         casper.click("li[data-section='user-list-admin']"); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
|  |  | ||||||
| // Test user deactivation and reactivation | // Test user deactivation and reactivation | ||||||
| casper.then(function () { | casper.then(function () { | ||||||
|     casper.waitForSelector('.user_row[id="user_cordelia@zulip.com"]', function () { |     casper.waitForSelector('.user_row[id="user_cordelia@zulip.com"]', function () { | ||||||
| @@ -52,8 +58,8 @@ casper.then(function () { | |||||||
|     casper.click('#settings-dropdown'); |     casper.click('#settings-dropdown'); | ||||||
|     casper.click('a[href^="#administration"]'); |     casper.click('a[href^="#administration"]'); | ||||||
|  |  | ||||||
|     casper.test.assertSelectorHasText("#administration a[aria-controls='deactivated-users']", "Deactivated users"); |     casper.test.assertSelectorHasText("li[data-section='deactivated-users-admin']", "Deactivated users"); | ||||||
|     casper.click("#administration a[aria-controls='deactivated-users']"); |     casper.click("li[data-section='deactivated-users-admin']"); | ||||||
|  |  | ||||||
|  |  | ||||||
|     casper.waitForSelector('#admin_deactivated_users_table .user_row[id="user_cordelia@zulip.com"] .reactivate', function () { |     casper.waitForSelector('#admin_deactivated_users_table .user_row[id="user_cordelia@zulip.com"] .reactivate', function () { | ||||||
| @@ -66,13 +72,15 @@ casper.then(function () { | |||||||
|     casper.waitForSelector('#admin_deactivated_users_table .user_row[id="user_cordelia@zulip.com"] button:not(.reactivate)', function () { |     casper.waitForSelector('#admin_deactivated_users_table .user_row[id="user_cordelia@zulip.com"] button:not(.reactivate)', function () { | ||||||
|         casper.test.assertSelectorHasText('#admin_deactivated_users_table .user_row[id="user_cordelia@zulip.com"]', 'Deactivate'); |         casper.test.assertSelectorHasText('#admin_deactivated_users_table .user_row[id="user_cordelia@zulip.com"]', 'Deactivate'); | ||||||
|     }); |     }); | ||||||
|  | }); | ||||||
|  |  | ||||||
|     casper.test.assertSelectorHasText("#administration a[aria-controls='organization']", "Organization"); | // Test bot deactivation and reactivation | ||||||
|     casper.click("#administration a[aria-controls='organization']"); | casper.then(function () { | ||||||
|  |     casper.test.assertSelectorHasText("li[data-section='organization-settings']", "Organization settings"); | ||||||
|  |     casper.click("li[data-section='bot-list-admin']"); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| casper.then(function () { | casper.then(function () { | ||||||
|     // Test bot deactivation and reactivation |  | ||||||
|     casper.waitForSelector('.user_row[id="user_new-user-bot@zulip.com"]', function () { |     casper.waitForSelector('.user_row[id="user_new-user-bot@zulip.com"]', function () { | ||||||
|         casper.test.assertSelectorHasText('.user_row[id="user_new-user-bot@zulip.com"]', 'Deactivate'); |         casper.test.assertSelectorHasText('.user_row[id="user_new-user-bot@zulip.com"]', 'Deactivate'); | ||||||
|         casper.click('.user_row[id="user_new-user-bot@zulip.com"] .deactivate'); |         casper.click('.user_row[id="user_new-user-bot@zulip.com"] .deactivate'); | ||||||
|   | |||||||
| @@ -12,6 +12,8 @@ exports.show_or_hide_menu_item = function () { | |||||||
|         item.show(); |         item.show(); | ||||||
|     } else { |     } else { | ||||||
|         item.hide(); |         item.hide(); | ||||||
|  |         $(".ind-tab[data-name='admin']").addClass("disabled"); | ||||||
|  |         $(".settings-list li.admin").hide(); | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -136,11 +138,8 @@ function get_non_default_streams_names(streams_data) { | |||||||
| } | } | ||||||
|  |  | ||||||
| exports.update_default_streams_table = function () { | exports.update_default_streams_table = function () { | ||||||
|     if (!meta.loaded) { |     if (/#*administration/.test(window.location.hash) || | ||||||
|         return; |         /#*settings/.test(window.location.hash)) { | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if ($('#administration').hasClass('active')) { |  | ||||||
|         $("#admin_default_streams_table").expectOne().find("tr.default_stream_row").remove(); |         $("#admin_default_streams_table").expectOne().find("tr.default_stream_row").remove(); | ||||||
|         populate_default_streams(page_params.realm_default_streams); |         populate_default_streams(page_params.realm_default_streams); | ||||||
|     } |     } | ||||||
| @@ -270,8 +269,9 @@ function _setup_page() { | |||||||
|         realm_default_language: page_params.realm_default_language, |         realm_default_language: page_params.realm_default_language, | ||||||
|         realm_waiting_period_threshold: page_params.realm_waiting_period_threshold, |         realm_waiting_period_threshold: page_params.realm_waiting_period_threshold, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     var admin_tab = templates.render('admin_tab', options); |     var admin_tab = templates.render('admin_tab', options); | ||||||
|     $("#administration").html(admin_tab); |     $("#settings_content .administration-box").html(admin_tab); | ||||||
|     $("#administration-status").expectOne().hide(); |     $("#administration-status").expectOne().hide(); | ||||||
|     $("#admin-realm-name-status").expectOne().hide(); |     $("#admin-realm-name-status").expectOne().hide(); | ||||||
|     $("#admin-realm-restricted-to-domain-status").expectOne().hide(); |     $("#admin-realm-restricted-to-domain-status").expectOne().hide(); | ||||||
| @@ -288,6 +288,20 @@ function _setup_page() { | |||||||
|     $('#admin-filter-pattern-status').expectOne().hide(); |     $('#admin-filter-pattern-status').expectOne().hide(); | ||||||
|     $('#admin-filter-format-status').expectOne().hide(); |     $('#admin-filter-format-status').expectOne().hide(); | ||||||
|  |  | ||||||
|  |     var tab = (function () { | ||||||
|  |         var tab = false; | ||||||
|  |         var hash_sequence = window.location.hash.split(/\//); | ||||||
|  |         if (/#*(administration)/.test(hash_sequence[0])) { | ||||||
|  |             tab = hash_sequence[1]; | ||||||
|  |             return tab || "organization-settings"; | ||||||
|  |         } | ||||||
|  |         return tab; | ||||||
|  |     }()); | ||||||
|  |  | ||||||
|  |     if (tab) { | ||||||
|  |         exports.launch_page(tab); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     $("#id_realm_default_language").val(page_params.realm_default_language); |     $("#id_realm_default_language").val(page_params.realm_default_language); | ||||||
|  |  | ||||||
|     // create loading indicators |     // create loading indicators | ||||||
| @@ -1014,6 +1028,17 @@ function _setup_page() { | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | exports.launch_page = function (tab) { | ||||||
|  |     var $active_tab = $("#settings_overlay_container li[data-section='" + tab + "']"); | ||||||
|  |  | ||||||
|  |     if ($active_tab.hasClass("admin")) { | ||||||
|  |         $(".sidebar .ind-tab[data-name='admin']").click(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $("#settings_overlay_container").addClass("show"); | ||||||
|  |     $active_tab.click(); | ||||||
|  | }; | ||||||
|  |  | ||||||
| exports.setup_page = function () { | exports.setup_page = function () { | ||||||
|     i18n.ensure_i18n(_setup_page); |     i18n.ensure_i18n(_setup_page); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -294,9 +294,10 @@ $(function () { | |||||||
|     popovers.register_click_handlers(); |     popovers.register_click_handlers(); | ||||||
|     notifications.register_click_handlers(); |     notifications.register_click_handlers(); | ||||||
|  |  | ||||||
|     $('.logout_button').click(function () { |     $('body').on('click', '.logout_button', function () { | ||||||
|         $('#logout_form').submit(); |         $('#logout_form').submit(); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     $('.restart_get_events_button').click(function () { |     $('.restart_get_events_button').click(function () { | ||||||
|         server_events.restart_get_events({dont_block: true}); |         server_events.restart_get_events({dont_block: true}); | ||||||
|     }); |     }); | ||||||
| @@ -558,6 +559,58 @@ $(function () { | |||||||
|     $('a.dropdown-toggle, .dropdown-menu a').on('touchstart', function (e) { |     $('a.dropdown-toggle, .dropdown-menu a').on('touchstart', function (e) { | ||||||
|         e.stopPropagation(); |         e.stopPropagation(); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  |     $("#settings_overlay_container .sidebar").on("click", "li[data-section]", function () { | ||||||
|  |         var $this = $(this); | ||||||
|  |  | ||||||
|  |         $("#settings_overlay_container .sidebar li").removeClass("active no-border"); | ||||||
|  |             $this.addClass("active"); | ||||||
|  |         $this.prev().addClass("no-border"); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     $("#settings_overlay_container .sidebar").on("click", "li[data-section]", function () { | ||||||
|  |         var $this = $(this); | ||||||
|  |         var section = $this.data("section"); | ||||||
|  |         var sel = "[data-name='" + section + "']"; | ||||||
|  |  | ||||||
|  |         $("#settings_overlay_container .sidebar li").removeClass("active no-border"); | ||||||
|  |         $this.addClass("active"); | ||||||
|  |         $this.prev().addClass("no-border"); | ||||||
|  |  | ||||||
|  |         if ($this.hasClass("admin")) { | ||||||
|  |             window.location.hash = "administration/" + section; | ||||||
|  |         } else { | ||||||
|  |             window.location.hash = "settings/" + section; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $(".settings-section, .settings-wrapper").removeClass("show"); | ||||||
|  |         $(".settings-section" + sel + ", .settings-wrapper" + sel).addClass("show"); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     $("#settings_overlay_container").on("click", function (e) { | ||||||
|  |         var $target = $(e.target); | ||||||
|  |         if ($target.is(".exit-sign, .exit")) { | ||||||
|  |             hashchange.exit_settings(); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     (function () { | ||||||
|  |         var $parent = $("#settings_overlay_container .sidebar .tab-switcher"); | ||||||
|  |         var $tabs = $parent.find(".ind-tab"); | ||||||
|  |         $tabs.click(function () { | ||||||
|  |             $tabs.removeClass("selected"); | ||||||
|  |             $(this).addClass("selected"); | ||||||
|  |  | ||||||
|  |             $(".sidebar li").hide(); | ||||||
|  |             if ($(this).data("name") === "admin") { | ||||||
|  |                 $("li.admin").show(); | ||||||
|  |                 $("li[data-section='organization-settings']").click(); | ||||||
|  |             } else { | ||||||
|  |                 $("li:not(.admin)").show(); | ||||||
|  |                 $("li[data-section='your-account']").click(); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     }()); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| return exports; | return exports; | ||||||
|   | |||||||
| @@ -48,12 +48,6 @@ exports.initialize = function () { | |||||||
|  |  | ||||||
|     // The admin and settings pages are generated client-side through |     // The admin and settings pages are generated client-side through | ||||||
|     // templates. |     // templates. | ||||||
|  |  | ||||||
|     var admin_link = $('#gear-menu a[href="#administration"]'); |  | ||||||
|     admin_link.on('shown', admin.setup_page); |  | ||||||
|  |  | ||||||
|     var settings_link = $('#gear-menu a[href="#settings"]'); |  | ||||||
|     settings_link.on('shown', settings.setup_page); |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| return exports; | return exports; | ||||||
|   | |||||||
| @@ -199,9 +199,9 @@ function do_hashchange(from_reload) { | |||||||
| // When going from a normal view (eg. `narrow/is/private`) to a settings panel | // When going from a normal view (eg. `narrow/is/private`) to a settings panel | ||||||
| // (eg. `settings/your-bots`) it should trigger the `should_ignore` function and | // (eg. `settings/your-bots`) it should trigger the `should_ignore` function and | ||||||
| // return `true` for the current state -- we want to ignore hash changes from | // return `true` for the current state -- we want to ignore hash changes from | ||||||
| // within the settings page, as they will be handled by the settings page itself. | // within the settings page. The previous hash however should return `false` as it | ||||||
| // | // was outside of the scope of settings. | ||||||
| // There is then an `exit_settings` function that allows the hash to change exactly | // there is then an `exit_settings` function that allows the hash to change exactly | ||||||
| // once without triggering any events. This allows the hash to reset back from | // once without triggering any events. This allows the hash to reset back from | ||||||
| // a settings page to the previous view available before the settings page | // a settings page to the previous view available before the settings page | ||||||
| // (eg. narrow/is/private). This saves the state, scroll position, and makes the | // (eg. narrow/is/private). This saves the state, scroll position, and makes the | ||||||
| @@ -211,24 +211,44 @@ var ignore = { | |||||||
|     flag: false, |     flag: false, | ||||||
|     prev: null, |     prev: null, | ||||||
|     old_hash: typeof window !== "undefined" ? window.location.hash : "#", |     old_hash: typeof window !== "undefined" ? window.location.hash : "#", | ||||||
|  |     group: null, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| function get_main_hash(hash) { | function get_main_hash(hash) { | ||||||
|     return hash.replace(/^#/, "").split(/\//)[0]; |     return hash ? hash.replace(/^#/, "").split(/\//)[0] : ""; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // different groups require different reloads. The grouped elements don't | ||||||
|  | // require a reload or overlay change to run. | ||||||
|  | var get_hash_group = (function () { | ||||||
|  |     var groups = [ | ||||||
|  |         ["subscriptions"], | ||||||
|  |         ["settings", "administration"], | ||||||
|  |     ]; | ||||||
|  |  | ||||||
|  |     return function (value) { | ||||||
|  |         var idx = null; | ||||||
|  |  | ||||||
|  |         _.find(groups, function (o, i) { | ||||||
|  |             if (o.indexOf(value) !== -1) { | ||||||
|  |                 idx = i; | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |             return false; | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         return idx; | ||||||
|  |     }; | ||||||
|  | }()); | ||||||
|  |  | ||||||
| function should_ignore(hash) { | function should_ignore(hash) { | ||||||
|     // an array of hashes to ignore (eg. ["subscriptions", "settings", "administration"]). |     // an array of hashes to ignore (eg. ["subscriptions", "settings", "administration"]). | ||||||
|     var ignore_list = ["subscriptions"]; |     var ignore_list = ["subscriptions", "settings", "administration"]; | ||||||
|     var main_hash = get_main_hash(hash); |     var main_hash = get_main_hash(hash); | ||||||
|  |  | ||||||
|     return (ignore_list.indexOf(main_hash) > -1); |     return (ignore_list.indexOf(main_hash) > -1); | ||||||
| } | } | ||||||
|  |  | ||||||
| function hide_overlays() { |  | ||||||
|     subs.close(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function hashchanged(from_reload, e) { | function hashchanged(from_reload, e) { | ||||||
|     var old_hash; |     var old_hash; | ||||||
|     if (e) { |     if (e) { | ||||||
| @@ -238,16 +258,32 @@ function hashchanged(from_reload, e) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     var base = get_main_hash(window.location.hash); |     var base = get_main_hash(window.location.hash); | ||||||
|  |  | ||||||
|     if (should_ignore(window.location.hash)) { |     if (should_ignore(window.location.hash)) { | ||||||
|         if (!should_ignore(old_hash || "#")) { |         // if the old has was a standard non-ignore hash OR the ignore hash | ||||||
|             if (base === "subscriptions") { |         // base has changed, something needs to run again. | ||||||
|                 subs.launch(); |  | ||||||
|  |         if (!should_ignore(old_hash || "#") || ignore.group !== get_hash_group(base)) { | ||||||
|  |             if (ignore.group !== get_hash_group(base)) { | ||||||
|  |                 exports.close_modals(); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             ignore.prev = old_hash; |             // now only if the previous one should not have been ignored. | ||||||
|  |             if (!should_ignore(old_hash || "#")) { | ||||||
|  |                 ignore.prev = old_hash; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (base === "subscriptions") { | ||||||
|  |                 subs.launch(); | ||||||
|  |             } else if (/settings|administration/.test(base)) { | ||||||
|  |                 settings.setup_page(); | ||||||
|  |                 admin.setup_page(); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             ignore.group = get_hash_group(base); | ||||||
|         } |         } | ||||||
|     } else if (!should_ignore(window.location.hash) && !ignore.flag) { |     } else if (!should_ignore(window.location.hash) && !ignore.flag) { | ||||||
|         hide_overlays(); |         exports.close_modals(); | ||||||
|         changing_hash = true; |         changing_hash = true; | ||||||
|         var ret = do_hashchange(from_reload); |         var ret = do_hashchange(from_reload); | ||||||
|         changing_hash = false; |         changing_hash = false; | ||||||
| @@ -270,6 +306,10 @@ exports.initialize = function () { | |||||||
|     hashchanged(true); |     hashchanged(true); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | exports.close_modals = function () { | ||||||
|  |     $("[data-overlay]").removeClass("show"); | ||||||
|  | }; | ||||||
|  |  | ||||||
| exports.exit_settings = function (callback) { | exports.exit_settings = function (callback) { | ||||||
|     if (should_ignore(window.location.hash)) { |     if (should_ignore(window.location.hash)) { | ||||||
|         ui.blur_active_element(); |         ui.blur_active_element(); | ||||||
| @@ -278,6 +318,8 @@ exports.exit_settings = function (callback) { | |||||||
|         if (typeof callback === "function") { |         if (typeof callback === "function") { | ||||||
|             callback(); |             callback(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         exports.close_modals(); | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,6 +7,10 @@ function do_narrow_action(action) { | |||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function is_settings_page() { | ||||||
|  |   return (/^#*(settings|administration)/g).test(window.location.hash); | ||||||
|  | } | ||||||
|  |  | ||||||
| var actions_dropdown_hotkeys = [ | var actions_dropdown_hotkeys = [ | ||||||
|     'down_arrow', |     'down_arrow', | ||||||
|     'up_arrow', |     'up_arrow', | ||||||
| @@ -213,6 +217,28 @@ function process_hotkey(e) { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     if (is_settings_page()) { | ||||||
|  |         if (event_name === 'up_arrow') { | ||||||
|  |             var prev = e.target.previousElementSibling; | ||||||
|  |  | ||||||
|  |             if ($(prev).css("display") !== "none") { | ||||||
|  |                 $(prev).focus().click(); | ||||||
|  |             } | ||||||
|  |             return true; | ||||||
|  |         } else if (event_name === 'down_arrow') { | ||||||
|  |             var next = e.target.nextElementSibling; | ||||||
|  |  | ||||||
|  |             if ($(next).css("display") !== "none") { | ||||||
|  |                 $(next).focus().click(); | ||||||
|  |             } | ||||||
|  |             return true; | ||||||
|  |         } else if (event_name === 'escape') { | ||||||
|  |             $("#settings_overlay_container .exit").click(); | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // Process hotkeys specially when in an input, select, textarea, or send button |     // Process hotkeys specially when in an input, select, textarea, or send button | ||||||
|     if ($('input:focus,select:focus,textarea:focus,#compose-send-button:focus').length > 0) { |     if ($('input:focus,select:focus,textarea:focus,#compose-send-button:focus').length > 0) { | ||||||
|         if (event_name === 'escape') { |         if (event_name === 'escape') { | ||||||
| @@ -256,7 +282,10 @@ function process_hotkey(e) { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (event_name === 'enter') { |         if (event_name === 'enter') { | ||||||
|             if (activity.searching()) { |             if (is_settings_page()) { | ||||||
|  |                 $(e.target).click(); | ||||||
|  |                 return true; | ||||||
|  |             } else if (activity.searching()) { | ||||||
|                 activity.blur_search(); |                 activity.blur_search(); | ||||||
|                 return true; |                 return true; | ||||||
|             } else if (stream_list.searching()) { |             } else if (stream_list.searching()) { | ||||||
| @@ -353,11 +382,17 @@ function process_hotkey(e) { | |||||||
|             navigate.to_end(); |             navigate.to_end(); | ||||||
|             return true; |             return true; | ||||||
|         case 'page_up': |         case 'page_up': | ||||||
|             navigate.page_up(); |             if (!is_settings_page()) { | ||||||
|             return true; |                 navigate.page_up(); | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|         case 'page_down': |         case 'page_down': | ||||||
|             navigate.page_down(); |             if (!is_settings_page()) { | ||||||
|             return true; |                 navigate.page_down(); | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Shortcuts that operate on a message |     // Shortcuts that operate on a message | ||||||
|   | |||||||
| @@ -149,6 +149,17 @@ function _setup_page() { | |||||||
|     // at page load. This promise will be resolved with a list of streams after |     // at page load. This promise will be resolved with a list of streams after | ||||||
|     // the first settings page load. build_stream_list then adds a callback to |     // the first settings page load. build_stream_list then adds a callback to | ||||||
|     // the promise, which in most cases will already be resolved. |     // the promise, which in most cases will already be resolved. | ||||||
|  |  | ||||||
|  |     var tab = (function () { | ||||||
|  |         var tab = false; | ||||||
|  |         var hash_sequence = window.location.hash.split(/\//); | ||||||
|  |         if (/#*(settings)/.test(hash_sequence[0])) { | ||||||
|  |             tab = hash_sequence[1]; | ||||||
|  |             return tab || "your-account"; | ||||||
|  |         } | ||||||
|  |         return tab; | ||||||
|  |     }()); | ||||||
|  |  | ||||||
|     if (_streams_deferred.state() !== "resolved") { |     if (_streams_deferred.state() !== "resolved") { | ||||||
|         channel.get({ |         channel.get({ | ||||||
|             url: '/json/streams', |             url: '/json/streams', | ||||||
| @@ -173,7 +184,7 @@ function _setup_page() { | |||||||
|         zuliprc: 'zuliprc', |         zuliprc: 'zuliprc', | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     $("#settings").html(settings_tab); |     $(".settings-box").html(settings_tab); | ||||||
|     $("#settings-status").hide(); |     $("#settings-status").hide(); | ||||||
|     $("#notify-settings-status").hide(); |     $("#notify-settings-status").hide(); | ||||||
|     $("#display-settings-status").hide(); |     $("#display-settings-status").hide(); | ||||||
| @@ -186,6 +197,10 @@ function _setup_page() { | |||||||
|     $("#show_api_key_box").hide(); |     $("#show_api_key_box").hide(); | ||||||
|     $("#api_key_button_box").show(); |     $("#api_key_button_box").show(); | ||||||
|  |  | ||||||
|  |     if (tab) { | ||||||
|  |         exports.launch_page(tab); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     function clear_password_change() { |     function clear_password_change() { | ||||||
|         // Clear the password boxes so that passwords don't linger in the DOM |         // Clear the password boxes so that passwords don't linger in the DOM | ||||||
|         // for an XSS attacker to find. |         // for an XSS attacker to find. | ||||||
| @@ -463,10 +478,14 @@ function _setup_page() { | |||||||
|         }); |         }); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  |     $("#default_language_modal [data-dismiss]").click(function () { | ||||||
|  |       $("#default_language_modal").fadeOut(300); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|     $("#default_language_modal .language").click(function (e) { |     $("#default_language_modal .language").click(function (e) { | ||||||
|         e.preventDefault(); |         e.preventDefault(); | ||||||
|         e.stopPropagation(); |         e.stopPropagation(); | ||||||
|         $('#default_language_modal').modal('hide'); |         $('#default_language_modal').fadeOut(300); | ||||||
|  |  | ||||||
|         var data = {}; |         var data = {}; | ||||||
|         var $link = $(e.target).closest("a[data-code]"); |         var $link = $(e.target).closest("a[data-code]"); | ||||||
| @@ -495,7 +514,7 @@ function _setup_page() { | |||||||
|     $('#default_language').on('click', function (e) { |     $('#default_language').on('click', function (e) { | ||||||
|         e.preventDefault(); |         e.preventDefault(); | ||||||
|         e.stopPropagation(); |         e.stopPropagation(); | ||||||
|         $('#default_language_modal').modal('show'); |         $('#default_language_modal').show().attr('aria-hidden', false); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     $("#user_deactivate_account_button").on('click', function (e) { |     $("#user_deactivate_account_button").on('click', function (e) { | ||||||
| @@ -835,6 +854,17 @@ exports.update_page = function () { | |||||||
|     i18n.ensure_i18n(_update_page); |     i18n.ensure_i18n(_update_page); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | exports.launch_page = function (tab) { | ||||||
|  |     var $active_tab = $("#settings_overlay_container li[data-section='" + tab + "']"); | ||||||
|  |  | ||||||
|  |     if (!$active_tab.hasClass("admin")) { | ||||||
|  |         $(".sidebar .ind-tab[data-name='settings']").click(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $("#settings_overlay_container").addClass("show"); | ||||||
|  |     $active_tab.click(); | ||||||
|  | }; | ||||||
|  |  | ||||||
| return exports; | return exports; | ||||||
| }()); | }()); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -111,6 +111,7 @@ td .button { | |||||||
| } | } | ||||||
|  |  | ||||||
| .settings-section { | .settings-section { | ||||||
|  |     display: none; | ||||||
|     background-color: #fafafa; |     background-color: #fafafa; | ||||||
|     border-radius: 2px; |     border-radius: 2px; | ||||||
|     margin: 20px; |     margin: 20px; | ||||||
| @@ -119,6 +120,20 @@ td .button { | |||||||
|     border-top: 5px solid #dfdfdf; |     border-top: 5px solid #dfdfdf; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #administration .settings-section { | ||||||
|  |     display: block; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .settings-wrapper { | ||||||
|  |     display: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .settings-section.show, | ||||||
|  | .settings-wrapper.show, | ||||||
|  | .settings-wrapper.show .settings-section { | ||||||
|  |     display: block; | ||||||
|  | } | ||||||
|  |  | ||||||
| .settings-section .settings-section-title { | .settings-section .settings-section-title { | ||||||
|     font-size: 1.2em; |     font-size: 1.2em; | ||||||
|     font-weight: 300; |     font-weight: 300; | ||||||
| @@ -485,6 +500,247 @@ input[type=checkbox].inline-block { | |||||||
|     height: 200px; |     height: 200px; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* -- new settings overlay -- */ | ||||||
|  | #settings_overlay_container { | ||||||
|  |     pointer-events: none; | ||||||
|  |     opacity: 0; | ||||||
|  |  | ||||||
|  |     position: fixed; | ||||||
|  |     top: 0; | ||||||
|  |     left: 0; | ||||||
|  |     width: 100vw; | ||||||
|  |     height: 100vh; | ||||||
|  |     overflow: auto; | ||||||
|  |  | ||||||
|  |     background-color: rgba(32,32,32,0.8); | ||||||
|  |     z-index: 105; | ||||||
|  |  | ||||||
|  |     transition: all 0.3s ease; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_overlay_container.show { | ||||||
|  |     pointer-events: all; | ||||||
|  |     opacity: 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_overlay_container.show #settings_page { | ||||||
|  |     -webkit-transform: scale(1); | ||||||
|  |     transform: scale(1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page { | ||||||
|  |     -webkit-transform: scale(0.5); | ||||||
|  |     transform: scale(0.5); | ||||||
|  |  | ||||||
|  |     background-color: rgba(0,0,0,0.8); | ||||||
|  |     z-index: 102; | ||||||
|  |     min-height: 550px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page { | ||||||
|  |     height: 95vh; | ||||||
|  |     width: 97vw; | ||||||
|  |     margin: 2.5vh 1.5vw; | ||||||
|  |     background-color: #fff; | ||||||
|  |     overflow: hidden; | ||||||
|  |     border-radius: 4px; | ||||||
|  |  | ||||||
|  |     -webkit-font-smoothing: antialiased; | ||||||
|  |     -moz-osx-font-smoothing: grayscale; | ||||||
|  |  | ||||||
|  |     transition: transform 0.2s ease; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .sidebar { | ||||||
|  |     float: left; | ||||||
|  |     position: relative; | ||||||
|  |     width: 250px; | ||||||
|  |     height: 100%; | ||||||
|  |     min-height: 550px; | ||||||
|  |     overflow-y: auto; | ||||||
|  |     border-top-left-radius: 4px; | ||||||
|  |     border-right: 1px solid #eee; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .sidebar .tab-container { | ||||||
|  |     background-color: #fff; | ||||||
|  |     padding: 6px; | ||||||
|  |     border-bottom: 1px solid #ddd; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .sidebar .settings-list { | ||||||
|  |     position: relative; | ||||||
|  |     z-index: 3; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .content-wrapper { | ||||||
|  |     position: relative; | ||||||
|  |     float: left; | ||||||
|  |     width: calc(100% - 250px - 1px); | ||||||
|  |     height: 100%; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .content-wrapper .settings-header { | ||||||
|  |     width: 100%; | ||||||
|  |     height: 43px; | ||||||
|  |     border-bottom: 1px solid #ddd; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .content-wrapper #settings_content { | ||||||
|  |     width: 100%; | ||||||
|  |     height: calc(100% - 60px); | ||||||
|  |  | ||||||
|  |     float: left; | ||||||
|  |     overflow-y: auto; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .sidebar .header { | ||||||
|  |     height: auto; | ||||||
|  |     position: relative; | ||||||
|  |     width: calc(100% - 20px); | ||||||
|  |     padding: 10px; | ||||||
|  |     text-align: center; | ||||||
|  |     text-transform: uppercase; | ||||||
|  |  | ||||||
|  |     background-color: #edefef; | ||||||
|  |     border-bottom: 1px solid #DDD; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .settings-header { | ||||||
|  |     padding-top: 1px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .settings-header h1 { | ||||||
|  |     text-align: center; | ||||||
|  |     font-size: 1.1em; | ||||||
|  |     line-height: 1; | ||||||
|  |     margin: 15px; | ||||||
|  |     text-transform: uppercase; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .settings-header .exit { | ||||||
|  |     font-weight: 400; | ||||||
|  |     position: absolute; | ||||||
|  |     top: 10px; | ||||||
|  |     right: 10px; | ||||||
|  |     color: #AAA; | ||||||
|  |     cursor: pointer; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .settings-header .exit-sign { | ||||||
|  |     float: right; | ||||||
|  |     position: relative; | ||||||
|  |     top: 3px; | ||||||
|  |     margin-left: 3px; | ||||||
|  |     font-size: 1.7em; | ||||||
|  |     font-weight: 500; | ||||||
|  |     cursor: pointer; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #deactivation_user_modal.fade.in { | ||||||
|  |     top: calc(50% - 120px); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #deactivate_self_modal { | ||||||
|  |     box-shadow: 0px 0px 75px rgba(0,0,0,0.5); | ||||||
|  |     outline: 10000px solid rgba(0,0,0,0.3); | ||||||
|  |     border: none; | ||||||
|  |     border-radius: 0px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input[type=text]#settings_search { | ||||||
|  |     width: calc(100% - 10px - 2px); | ||||||
|  |     margin: 0px; | ||||||
|  |  | ||||||
|  |     color: #555; | ||||||
|  |     font-size: 0.9rem; | ||||||
|  |     padding: 3px 5px; | ||||||
|  |     outline: none; | ||||||
|  |     border: 1px solid #DDD; | ||||||
|  |     border-radius: 4px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input[type=text]:focus#settings_search { | ||||||
|  |     box-shadow: none; | ||||||
|  |     border: 1px solid #BBB; | ||||||
|  |  | ||||||
|  |     border-bottom: 1px solid #DDD; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input[type=text]#settings_search { | ||||||
|  |     width: calc(100% - 10px - 2px); | ||||||
|  |     margin: 0px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .sidebar ul { | ||||||
|  |     list-style: none; | ||||||
|  |     margin: 0; | ||||||
|  |     padding: 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .sidebar li { | ||||||
|  |     padding: 5px 0px; | ||||||
|  |     outline: none; | ||||||
|  |     cursor: pointer; | ||||||
|  |     transition: all 0.2s ease; | ||||||
|  |     border-bottom: 1px solid #eee; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .sidebar li.no-border { | ||||||
|  |     border-color: transparent; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .sidebar li.active { | ||||||
|  |     background-color: #eee; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .sidebar li.active { | ||||||
|  |     border-bottom: 1px solid transparent; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .sidebar li .text, | ||||||
|  | #settings_page .sidebar li .icon { | ||||||
|  |     display: inline-block; | ||||||
|  |     vertical-align: top; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .sidebar li .text { | ||||||
|  |     width: calc(100% - 55px); | ||||||
|  |     padding: 10px 12px 10px 0px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .sidebar li .icon { | ||||||
|  |     width: 18px; | ||||||
|  |     height: 18px; | ||||||
|  |     margin: 10px 10px; | ||||||
|  |  | ||||||
|  |     font-size: 1.4em; | ||||||
|  |     color: #888; | ||||||
|  |  | ||||||
|  |     background-size: cover; | ||||||
|  |     background-repeat: no-repeat; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .sidebar li.admin { | ||||||
|  |     display: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .sidebar li.admin .icon { | ||||||
|  |     text-align: center; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .sidebar li:last-of-type .text { | ||||||
|  |     border-bottom: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #settings_page .sidebar .sidebar-bottom-anchor { | ||||||
|  |     width: 100%; | ||||||
|  |     position: absolute; | ||||||
|  |     bottom: 0px; | ||||||
|  | } | ||||||
|  | /* -- end new settings overlay -- */ | ||||||
|  |  | ||||||
| @media (max-width: 1215px) { | @media (max-width: 1215px) { | ||||||
|     .user-avatar-section { |     .user-avatar-section { | ||||||
|         float: none; |         float: none; | ||||||
| @@ -505,6 +761,12 @@ input[type=checkbox].inline-block { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @media (max-width: 953px) { | ||||||
|  |     #settings_content .warning { | ||||||
|  |         display: none; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| #show_api_key_box { | #show_api_key_box { | ||||||
|     padding-bottom: 20px; |     padding-bottom: 20px; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1962,11 +1962,6 @@ div.floating_recipient { | |||||||
|     table-layout: fixed; |     table-layout: fixed; | ||||||
| } | } | ||||||
|  |  | ||||||
| .administration { |  | ||||||
|     margin-top: 55px; |  | ||||||
|     padding-left: 15px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .conversation-partners { | .conversation-partners { | ||||||
|     display: block; |     display: block; | ||||||
|     line-height: 1.2em; |     line-height: 1.2em; | ||||||
|   | |||||||
| @@ -1,55 +1,23 @@ | |||||||
| <div class="row-fluid"> | <div class="alert" id="administration-status"></div> | ||||||
|   <div class="span12"> |  | ||||||
|     <div class="administration"> |  | ||||||
|       <div class="alert" id="administration-status"></div> |  | ||||||
|       <h1><i class="icon-vector-bolt administration-icon"></i>{{t "Administration" }}</h1> |  | ||||||
|       <ul class="nav nav-tabs" role="tablist"> |  | ||||||
|         <li role="presentation" class="active"> |  | ||||||
|           <a href="#organization" aria-controls="organization" role="tab" data-toggle="tab"><i class="icon-vector-gear settings-section-icon"></i> {{t "Organization settings" }}</a> |  | ||||||
|         </li> |  | ||||||
|         <li role="presentation"> |  | ||||||
|           <a href="#users" aria-controls="users" role="tab" data-toggle="tab"><i class="icon-vector-user settings-section-icon"></i> {{t "Users" }}</a> |  | ||||||
|         </li> |  | ||||||
|         <li role="presentation"> |  | ||||||
|           <a href="#deactivated-users" aria-controls="deactivated-users" role="tab" data-toggle="tab"><i class="icon-vector-trash settings-section-icon"></i> {{t "Deactivated users" }}</a> |  | ||||||
|         </li> |  | ||||||
|         <li role="presentation"> |  | ||||||
|           <a href="#bots" aria-controls="bots" role="tab" data-toggle="tab"><i class="icon-vector-github settings-section-icon"></i> {{t "Bots" }}</a> |  | ||||||
|         </li> |  | ||||||
|         <li role="presentation"> |  | ||||||
|           <a href="#streams" aria-controls="streams" role="tab" data-toggle="tab"><i class="icon-vector-exchange settings-section-icon"></i> {{t "Delete streams" }}</a> |  | ||||||
|         </li> |  | ||||||
|         <li role="presentation"> |  | ||||||
|           <a href="#default-streams" aria-controls="default-streams" role="tab" data-toggle="tab"><i class="icon-vector-exchange settings-section-icon"></i> {{t "Default streams" }}</a> |  | ||||||
|         </li> |  | ||||||
|       </ul> |  | ||||||
|       <div class="tab-content"> |  | ||||||
|         <div role="tabpanel" class="tab-pane active" id="organization"> |  | ||||||
|           {{ partial "organization-settings-admin" }} |  | ||||||
|           {{ partial "emoji-settings-admin" }} |  | ||||||
|           {{ partial "realm-filter-settings-admin" }} |  | ||||||
|           {{ partial "auth-methods-settings-admin" }} |  | ||||||
|         </div> |  | ||||||
|         <div role="tabpanel" class="tab-pane" id="users"> |  | ||||||
|           {{ partial "user-list-admin" }} |  | ||||||
|         </div> |  | ||||||
|         <div role="tabpanel" class="tab-pane" id="deactivated-users"> |  | ||||||
|           {{ partial "deactivated-users-admin" }} |  | ||||||
|         </div> |  | ||||||
|         <div role="tabpanel" class="tab-pane" id="bots"> |  | ||||||
|           {{ partial "bot-list-admin" }} |  | ||||||
|         </div> |  | ||||||
|         <div role="tabpanel" class="tab-pane" id="streams"> |  | ||||||
|           {{ partial "streams-list-admin" }} |  | ||||||
|         </div> |  | ||||||
|         <div role="tabpanel" class="tab-pane" id="default-streams"> |  | ||||||
|           {{ partial "default-streams-list-admin" }} |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|  |  | ||||||
|       {{ partial "deactivation-user-modal" }} | {{ partial "deactivation-user-modal" }} | ||||||
|       {{ partial "deactivation-stream-modal" }} | {{ partial "deactivation-stream-modal" }} | ||||||
|       {{ partial "realm-domains-modal" }} | {{ partial "realm-domains-modal" }} | ||||||
|     </div> |  | ||||||
|   </div> | {{ partial "organization-settings-admin" }} | ||||||
| </div> |  | ||||||
|  | {{ partial "emoji-settings-admin" }} | ||||||
|  |  | ||||||
|  | {{ partial "user-list-admin" }} | ||||||
|  |  | ||||||
|  | {{ partial "deactivated-users-admin" }} | ||||||
|  |  | ||||||
|  | {{ partial "bot-list-admin" }} | ||||||
|  |  | ||||||
|  | {{ partial "streams-list-admin" }} | ||||||
|  |  | ||||||
|  | {{ partial "default-streams-list-admin" }} | ||||||
|  |  | ||||||
|  | {{ partial "auth-methods-settings-admin" }} | ||||||
|  |  | ||||||
|  | {{ partial "realm-filter-settings-admin" }} | ||||||
|   | |||||||
| @@ -1,5 +1,3 @@ | |||||||
| <h1><i class="icon-vector-wrench settings-icon"></i>{{t "Settings" }}</h1> |  | ||||||
|  |  | ||||||
| <div id="settings-change-box" class="new-style"> | <div id="settings-change-box" class="new-style"> | ||||||
|     <div class="alert" id="settings-status"></div> |     <div class="alert" id="settings-status"></div> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| <div id="subscription_overlay" class="new-style"> | <div id="subscription_overlay" class="new-style" data-overlay="subscriptions"> | ||||||
|     <div class="flex"> |     <div class="flex"> | ||||||
|         <div class="subscriptions-container"> |         <div class="subscriptions-container"> | ||||||
|             <div class="subscriptions-header"> |             <div class="subscriptions-header"> | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								static/third/bootstrap/css/bootstrap.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								static/third/bootstrap/css/bootstrap.css
									
									
									
									
										vendored
									
									
								
							| @@ -3774,7 +3774,7 @@ button.close { | |||||||
|   right: 0; |   right: 0; | ||||||
|   bottom: 0; |   bottom: 0; | ||||||
|   left: 0; |   left: 0; | ||||||
|   z-index: 1040; |   z-index: 101; | ||||||
|   background-color: #000000; |   background-color: #000000; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -60,6 +60,9 @@ var page_params = {{ page_params }}; | |||||||
| <div id="right-screen" class="screen"></div> | <div id="right-screen" class="screen"></div> | ||||||
| <div id="clear-screen" class="screen"></div> | <div id="clear-screen" class="screen"></div> | ||||||
|  |  | ||||||
|  | <div id="settings_overlay_container" data-overlay="settings"> | ||||||
|  |   {% include "zerver/settings_overlay.html" %} | ||||||
|  | </div> | ||||||
| {% include "zerver/navbar.html" %} | {% include "zerver/navbar.html" %} | ||||||
|  |  | ||||||
| <div class="fixed-app"> | <div class="fixed-app"> | ||||||
|   | |||||||
| @@ -55,12 +55,12 @@ | |||||||
|                     </a> |                     </a> | ||||||
|                   </li> |                   </li> | ||||||
|                   <li title="{{ _('Settings') }}"> |                   <li title="{{ _('Settings') }}"> | ||||||
|                     <a href="#settings" data-toggle="tab"> |                     <a href="#settings"> | ||||||
|                       <i class="icon-vector-wrench"></i> {{ _('Settings') }} |                       <i class="icon-vector-wrench"></i> {{ _('Settings') }} | ||||||
|                     </a> |                     </a> | ||||||
|                   </li> |                   </li> | ||||||
|                   <li title="{{ _('Administration') }}" class="admin-menu-item"> |                   <li title="{{ _('Administration') }}" class="admin-menu-item"> | ||||||
|                     <a href="#administration" role="button" data-toggle="tab"> |                     <a href="#administration" role="button"> | ||||||
|                       <i class="icon-vector-bolt"></i> {{ _('Administration') }} |                       <i class="icon-vector-bolt"></i> {{ _('Administration') }} | ||||||
|                     </a> |                     </a> | ||||||
|                   </li> |                   </li> | ||||||
|   | |||||||
							
								
								
									
										100
									
								
								templates/zerver/settings_overlay.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								templates/zerver/settings_overlay.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | |||||||
|  | <div id="settings_page" class="new-style"> | ||||||
|  |   <div class="sidebar"> | ||||||
|  |     <div class="sidebar-list dark-grey small-text"> | ||||||
|  |       <div class="center tab-container"> | ||||||
|  |         <div class="tab-switcher"> | ||||||
|  |           <div class="ind-tab first selected" data-name="settings">{{ _('Settings') }}</div> | ||||||
|  |           <div class="ind-tab second" data-name="admin">{{ _('Administration') }} </div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <ul class="settings-list"> | ||||||
|  |         <li tabindex="1" class="active" data-section="your-account"> | ||||||
|  |           <div class="icon icon-vector-user"></div> | ||||||
|  |           <div class="text">{{ _('Your account') }}</div> | ||||||
|  |         </li> | ||||||
|  |         <li tabindex="1" data-section="display-settings"> | ||||||
|  |           <div class="icon icon-vector-time"></div> | ||||||
|  |           <div class="text">{{ _('Display settings') }}</div> | ||||||
|  |         </li> | ||||||
|  |         <li tabindex="1" data-section="notifications"> | ||||||
|  |           <div class="icon icon-vector-warning-sign"></div> | ||||||
|  |           <div class="text">{{ _('Notifications') }}</div> | ||||||
|  |         </li> | ||||||
|  |         <li tabindex="1" data-section="your-bots"> | ||||||
|  |           <div class="icon icon-vector-github"></div> | ||||||
|  |           <div class="text">{{ _('Your bots') }}</div> | ||||||
|  |         </li> | ||||||
|  |         <li tabindex="1" data-section="custom-alert-words"> | ||||||
|  |           <div class="icon icon-vector-book"></div> | ||||||
|  |           <div class="text">{{ _('Custom alert words') }}</div> | ||||||
|  |         </li> | ||||||
|  |         <li tabindex="1" data-section="zulip-labs"> | ||||||
|  |           <i class="icon icon-vector-beaker"></i> | ||||||
|  |           <div class="text">{{ _('Zulip labs') }}</div> | ||||||
|  |         </li> | ||||||
|  |  | ||||||
|  |         <li class="admin" tabindex="1" data-section="organization-settings"> | ||||||
|  |           <i class="icon icon-vector-beaker"></i> | ||||||
|  |           <div class="text">{{ _('Organization settings') }}</div> | ||||||
|  |         </li> | ||||||
|  |         <li class="admin" tabindex="1" data-section="emoji-settings"> | ||||||
|  |           <i class="icon icon-vector-smile"></i> | ||||||
|  |           <div class="text">{{ _('Custom emoji') }}</div> | ||||||
|  |         </li> | ||||||
|  |         <li class="admin" tabindex="1" data-section="auth-methods"> | ||||||
|  |           <i class="icon icon-vector-lock"></i> | ||||||
|  |           <div class="text">{{ _('Authentication methods') }}</div> | ||||||
|  |         </li> | ||||||
|  |         <li class="admin" tabindex="1" data-section="user-list-admin"> | ||||||
|  |           <i class="icon icon-vector-user"></i> | ||||||
|  |           <div class="text">{{ _('Users') }}</div> | ||||||
|  |         </li> | ||||||
|  |         <li class="admin" tabindex="1" data-section="deactivated-users-admin"> | ||||||
|  |           <i class="icon icon-vector-trash"></i> | ||||||
|  |           <div class="text">{{ _('Deactivated users') }}</div> | ||||||
|  |         </li> | ||||||
|  |         <li class="admin" tabindex="1" data-section="bot-list-admin"> | ||||||
|  |           <i class="icon icon-vector-github"></i> | ||||||
|  |           <div class="text">{{ _('Bots') }}</div> | ||||||
|  |         </li> | ||||||
|  |         <li class="admin" tabindex="1" data-section="streams-list-admin"> | ||||||
|  |           <i class="icon icon-vector-exchange"></i> | ||||||
|  |           <div class="text">{{ _('Delete streams') }}</div> | ||||||
|  |         </li> | ||||||
|  |         <li class="admin" tabindex="1" data-section="default-streams-list"> | ||||||
|  |           <i class="icon icon-vector-exchange"></i> | ||||||
|  |           <div class="text">{{ _('Default streams') }}</div> | ||||||
|  |         </li> | ||||||
|  |         <li class="admin" tabindex="1" data-section="filter-settings"> | ||||||
|  |           <i class="icon icon-vector-font"></i> | ||||||
|  |           <div class="text">{{ _('Filter settings') }}</div> | ||||||
|  |         </li> | ||||||
|  |       </ul> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <div class="sidebar-bottom-anchor dark-grey small-text"> | ||||||
|  |       <ul> | ||||||
|  |         <li> | ||||||
|  |           <div class="icon icon-vector-off"></div> | ||||||
|  |           <a href="#logout" class="no-style logout_button"><div class="text">Log Out</div></a> | ||||||
|  |         </li> | ||||||
|  |       </ul> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  |   <div class="content-wrapper"> | ||||||
|  |     <div class="settings-header"> | ||||||
|  |       <h1>{{ _('Settings') }}</h1> | ||||||
|  |       <div class="exit"> | ||||||
|  |           <span class="exit-sign">×</span> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |     <div id="settings_content"> | ||||||
|  |         <div class="administration-box administration"> | ||||||
|  |  | ||||||
|  |         </div> | ||||||
|  |         <div class="settings-box"> | ||||||
|  |  | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
| @@ -18,6 +18,7 @@ GENERIC_KEYWORDS = [ | |||||||
|     'show', |     'show', | ||||||
|     'notdisplayed', |     'notdisplayed', | ||||||
|     'popover', |     'popover', | ||||||
|  |     'no-border', | ||||||
|     'success', |     'success', | ||||||
|     'text-error', |     'text-error', | ||||||
|     'warning', |     'warning', | ||||||
| @@ -25,6 +26,7 @@ GENERIC_KEYWORDS = [ | |||||||
|     'zoom-out', |     'zoom-out', | ||||||
|     'first', |     'first', | ||||||
|     'second', |     'second', | ||||||
|  |     'selected', | ||||||
| ] | ] | ||||||
|  |  | ||||||
| def raise_error(fn, i, line): | def raise_error(fn, i, line): | ||||||
|   | |||||||
| @@ -72,6 +72,7 @@ class TemplateTestCase(ZulipTestCase): | |||||||
|             'zerver/navbar.html', |             'zerver/navbar.html', | ||||||
|             'zerver/right-sidebar.html', |             'zerver/right-sidebar.html', | ||||||
|             'zerver/search_operators.html', |             'zerver/search_operators.html', | ||||||
|  |             'zerver/settings_overlay.html', | ||||||
|             'zerver/stream_creation_prompt.html', |             'zerver/stream_creation_prompt.html', | ||||||
|             'zerver/subscriptions.html', |             'zerver/subscriptions.html', | ||||||
|             'zerver/tutorial_finale.html', |             'zerver/tutorial_finale.html', | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user