summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/sidebar.js.es6
diff options
context:
space:
mode:
authorMike Greiling <mike@pixelcog.com>2016-09-02 01:33:43 -0500
committerMike Greiling <mike@pixelcog.com>2016-09-07 14:02:21 -0500
commitb2f8ebbb4295e5f070187050e094db87ff9d6ad0 (patch)
treeb743850b7043d4585bcca6a5e126c5519ecc4f19 /app/assets/javascripts/sidebar.js.es6
parent6690fc70478b4d82c49689e9e13e414bc77bb271 (diff)
downloadgitlab-ce-b2f8ebbb4295e5f070187050e094db87ff9d6ad0.tar.gz
refactor sidebar logic into singleton class
Diffstat (limited to 'app/assets/javascripts/sidebar.js.es6')
-rw-r--r--app/assets/javascripts/sidebar.js.es698
1 files changed, 98 insertions, 0 deletions
diff --git a/app/assets/javascripts/sidebar.js.es6 b/app/assets/javascripts/sidebar.js.es6
new file mode 100644
index 00000000000..737f343ed0d
--- /dev/null
+++ b/app/assets/javascripts/sidebar.js.es6
@@ -0,0 +1,98 @@
+((global) => {
+ let singleton;
+
+ const pinnedStateCookie = 'pin_nav';
+ const sidebarBreakpoint = 1024;
+
+ const pageSelector = '.page-with-sidebar';
+ const navbarSelector = '.navbar-fixed-top';
+ const sidebarWrapperSelector = '.sidebar-wrapper';
+ const sidebarContentSelector = '.nav-sidebar';
+
+ const pinnedToggleSelector = '.js-nav-pin';
+ const sidebarToggleSelector = '.toggle-nav-collapse, .side-nav-toggle';
+
+ const pinnedPageClass = 'page-sidebar-pinned';
+ const expandedPageClass = 'page-sidebar-expanded';
+ const collapsedPageClass = 'page-sidebar-collapsed';
+
+ const pinnedNavbarClass = 'header-pinned-nav';
+ const expandedNavbarClass = 'header-expanded';
+ const collapsedNavbarClass = 'header-collapsed';
+
+ class Sidebar {
+ constructor() {
+ if (!singleton) {
+ singleton = this;
+ singleton.init();
+ } else {
+ singleton.renderState();
+ }
+ return singleton;
+ }
+
+ init() {
+ this.isPinned = $.cookie(pinnedStateCookie) === 'true';
+ this.isExpanded = (
+ window.innerWidth >= sidebarBreakpoint &&
+ $(pageSelector).hasClass(expandedPageClass)
+ );
+ $(document)
+ .on('click', sidebarToggleSelector, () => this.toggleSidebar())
+ .on('click', pinnedToggleSelector, () => this.togglePinnedState())
+ .on('click', 'html, body', (e) => this.handleClickEvent(e));
+ this.renderState();
+ }
+
+ handleClickEvent(e) {
+ if (this.isExpanded && (!this.isPinned || window.innerWidth < sidebarBreakpoint)) {
+ const $target = $(e.target);
+ const targetIsToggle = $target.closest(sidebarToggleSelector).length > 0;
+ const targetIsSidebar = $target.closest(sidebarWrapperSelector).length > 0;
+ if (!targetIsToggle && (!targetIsSidebar || $target.closest('a'))) {
+ this.toggleSidebar();
+ }
+ }
+ }
+
+ toggleSidebar() {
+ this.isExpanded = !this.isExpanded;
+ this.renderState();
+ }
+
+ togglePinnedState() {
+ this.isPinned = !this.isPinned;
+ if (!this.isPinned) {
+ this.isExpanded = false;
+ }
+ $.cookie(pinnedStateCookie, this.isPinned ? 'true' : 'false', {
+ path: gon.relative_url_root || '/',
+ expires: 3650
+ });
+ this.renderState();
+ }
+
+ renderState() {
+ $(pageSelector)
+ .toggleClass(pinnedPageClass, this.isPinned && this.isExpanded)
+ .toggleClass(expandedPageClass, this.isExpanded)
+ .toggleClass(collapsedPageClass, !this.isExpanded);
+ $(navbarSelector)
+ .toggleClass(pinnedNavbarClass, this.isPinned && this.isExpanded)
+ .toggleClass(expandedNavbarClass, this.isExpanded)
+ .toggleClass(collapsedNavbarClass, !this.isExpanded);
+
+ const $pinnedToggle = $(pinnedToggleSelector);
+ const tooltipText = this.isPinned ? 'Unpin navigation' : 'Pin navigation';
+ const tooltipState = $pinnedToggle.attr('aria-describedby') && this.isExpanded ? 'show' : 'hide';
+ $pinnedToggle.attr('title', tooltipText).tooltip('fixTitle').tooltip(tooltipState);
+
+ if (this.isExpanded) {
+ setTimeout(() => $(sidebarContentSelector).niceScroll().updateScrollBar(), 200);
+ }
+ }
+ }
+
+ global.Sidebar = Sidebar;
+
+})(window.gl || (window.gl = {}));