diff options
Diffstat (limited to 'app/assets/javascripts/user_tabs.js.coffee')
-rw-r--r-- | app/assets/javascripts/user_tabs.js.coffee | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/app/assets/javascripts/user_tabs.js.coffee b/app/assets/javascripts/user_tabs.js.coffee new file mode 100644 index 00000000000..09b7eec9104 --- /dev/null +++ b/app/assets/javascripts/user_tabs.js.coffee @@ -0,0 +1,146 @@ +# UserTabs +# +# Handles persisting and restoring the current tab selection and lazily-loading +# content on the Users#show page. +# +# ### Example Markup +# +# <ul class="nav-links"> +# <li class="activity-tab active"> +# <a data-action="activity" data-target="#activity" data-toggle="tab" href="/u/username"> +# Activity +# </a> +# </li> +# <li class="groups-tab"> +# <a data-action="groups" data-target="#groups" data-toggle="tab" href="/u/username/groups"> +# Groups +# </a> +# </li> +# <li class="contributed-tab"> +# <a data-action="contributed" data-target="#contributed" data-toggle="tab" href="/u/username/contributed"> +# Contributed projects +# </a> +# </li> +# <li class="projects-tab"> +# <a data-action="projects" data-target="#projects" data-toggle="tab" href="/u/username/projects"> +# Personal projects +# </a> +# </li> +# </ul> +# +# <div class="tab-content"> +# <div class="tab-pane" id="activity"> +# Activity Content +# </div> +# <div class="tab-pane" id="groups"> +# Groups Content +# </div> +# <div class="tab-pane" id="contributed"> +# Contributed projects content +# </div> +# <div class="tab-pane" id="projects"> +# Projects content +# </div> +# </div> +# +# <div class="loading-status"> +# <div class="loading"> +# Loading Animation +# </div> +# </div> +# +class @UserTabs + constructor: (opts) -> + { + @action = 'activity' + @defaultAction = 'activity' + @parentEl = $(document) + } = opts + + # Make jQuery object if selector is provided + @parentEl = $(@parentEl) if typeof @parentEl is 'string' + + # Store the `location` object, allowing for easier stubbing in tests + @_location = location + + # Set tab states + @loaded = {} + for item in @parentEl.find('.nav-links a') + @loaded[$(item).attr 'data-action'] = false + + # Actions + @actions = Object.keys @loaded + + @bindEvents() + + # Set active tab + @action = @defaultAction if @action is 'show' + @activateTab(@action) + + bindEvents: -> + # Toggle event listeners + @parentEl + .off 'shown.bs.tab', '.nav-links a[data-toggle="tab"]' + .on 'shown.bs.tab', '.nav-links a[data-toggle="tab"]', @tabShown + + tabShown: (event) => + $target = $(event.target) + action = $target.data('action') + source = $target.attr('href') + + @setTab(source, action) + @setCurrentAction(action) + + activateTab: (action) -> + @parentEl.find(".nav-links .#{action}-tab a").tab('show') + + setTab: (source, action) -> + return if @loaded[action] is true + + if action is 'activity' + @loadActivities(source) + + if action in ['groups', 'contributed', 'projects'] + @loadTab(source, action) + + loadTab: (source, action) -> + $.ajax + beforeSend: => @toggleLoading(true) + complete: => @toggleLoading(false) + dataType: 'json' + type: 'GET' + url: "#{source}.json" + success: (data) => + tabSelector = 'div#' + action + @parentEl.find(tabSelector).html(data.html) + @loaded[action] = true + + loadActivities: (source) -> + return if @loaded['activity'] is true + + $calendarWrap = @parentEl.find('.user-calendar') + $calendarWrap.load($calendarWrap.data('href')) + + new Activities() + @loaded['activity'] = true + + toggleLoading: (status) -> + @parentEl.find('.loading-status .loading').toggle(status) + + setCurrentAction: (action) -> + # Remove possible actions from URL + regExp = new RegExp('\/(' + @actions.join('|') + ')(\.html)?\/?$') + new_state = @_location.pathname + new_state = new_state.replace(/\/+$/, "") # remove trailing slashes + new_state = new_state.replace(regExp, '') + + # Append the new action if we're on a tab other than 'activity' + unless action == @defaultAction + new_state += "/#{action}" + + # Ensure parameters and hash come along for the ride + new_state += @_location.search + @_location.hash + + history.replaceState {turbolinks: true, url: new_state}, document.title, new_state + + new_state |