BigW Consortium Gitlab

user_tabs.js.coffee 3.99 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
# 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>
#
52
class @UserTabs
53 54 55
  constructor: (opts) ->
    {
      @action = 'activity'
56
      @defaultAction = 'activity'
57 58 59 60 61
      @parentEl = $(document)
    } = opts

    # Make jQuery object if selector is provided
    @parentEl = $(@parentEl) if typeof @parentEl is 'string'
62 63 64

    # Store the `location` object, allowing for easier stubbing in tests
    @_location = location
65 66

    # Set tab states
Alfredo Sumaran committed
67
    @loaded = {}
68 69
    for item in @parentEl.find('.nav-links a')
      @loaded[$(item).attr 'data-action'] = false
70

71 72
    # Actions
    @actions = Object.keys @loaded
Alfredo Sumaran committed
73

74
    @bindEvents()
75 76

    # Set active tab
77 78
    @action = @defaultAction if @action is 'show'
    @activateTab(@action)
79 80

  bindEvents: ->
Alfredo Sumaran committed
81 82 83 84
    # 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
Alfredo Sumaran committed
85

86 87 88 89 90
  tabShown: (event) =>
    $target = $(event.target)
    action = $target.data('action')
    source = $target.attr('href')

Alfredo Sumaran committed
91
    @setTab(source, action)
92 93
    @setCurrentAction(action)

94
  activateTab: (action) ->
95
    @parentEl.find(".nav-links .#{action}-tab a").tab('show')
96

Alfredo Sumaran committed
97 98 99 100 101 102
  setTab: (source, action) ->
    return if @loaded[action] is true

    if action is 'activity'
      @loadActivities(source)

103
    if action in ['groups', 'contributed', 'projects']
Alfredo Sumaran committed
104 105
      @loadTab(source, action)

106
  loadTab: (source, action) ->
Alfredo Sumaran committed
107 108 109 110 111
    $.ajax
      beforeSend: => @toggleLoading(true)
      complete:   => @toggleLoading(false)
      dataType: 'json'
      type: 'GET'
112 113 114
      url: "#{source}.json"
      success: (data) =>
        tabSelector = 'div#' + action
115
        @parentEl.find(tabSelector).html(data.html)
Alfredo Sumaran committed
116
        @loaded[action] = true
117

Alfredo Sumaran committed
118 119
  loadActivities: (source) ->
    return if @loaded['activity'] is true
120

121
    $calendarWrap = @parentEl.find('.user-calendar')
122
    $calendarWrap.load($calendarWrap.data('href'))
123

Alfredo Sumaran committed
124 125
    new Activities()
    @loaded['activity'] = true
126

Alfredo Sumaran committed
127
  toggleLoading: (status) ->
128
    @parentEl.find('.loading-status .loading').toggle(status)
129 130 131 132

  setCurrentAction: (action) ->
    # Remove possible actions from URL
    regExp = new RegExp('\/(' + @actions.join('|') + ')(\.html)?\/?$')
133 134 135
    new_state = @_location.pathname
    new_state = new_state.replace(/\/+$/, "") # remove trailing slashes
    new_state = new_state.replace(regExp, '')
136 137 138 139 140 141 142 143 144 145 146

    # 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