# Creates the variables for setting up GFM auto-completion window.GitLab ?= {} GitLab.GfmAutoComplete = dataLoading: false dataLoaded: false dataSource: '' # Emoji Emoji: template: '
  • ${name} ${name}
  • ' # Team Members Members: template: '
  • ${username} ${title}
  • ' # Issues and MergeRequests Issues: template: '
  • ${id} ${title}
  • ' # Milestones Milestones: template: '
  • ${title}
  • ' Loading: template: '
  • Loading...
  • ' DefaultOptions: sorter: (query, items, searchKey) -> return items if items[0].name? and items[0].name is 'loading' $.fn.atwho.default.callbacks.sorter(query, items, searchKey) filter: (query, data, searchKey) -> return data if data[0] is 'loading' $.fn.atwho.default.callbacks.filter(query, data, searchKey) beforeInsert: (value) -> if not GitLab.GfmAutoComplete.dataLoaded @at else value # Add GFM auto-completion to all input fields, that accept GFM input. setup: (wrap) -> @input = $('.js-gfm-input') # destroy previous instances @destroyAtWho() # set up instances @setupAtWho() if @dataSource if !@dataLoading @dataLoading = true # We should wait until initializations are done # and only trigger the last .setup since # The previous .dataSource belongs to the previous issuable # and the last one will have the **proper** .dataSource property # TODO: Make this a singleton and turn off events when moving to another page setTimeout( => fetch = @fetchData(@dataSource) fetch.done (data) => @dataLoading = false @loadData(data) , 1000) setupAtWho: -> # Emoji @input.atwho at: ':' displayTpl: (value) => if value.path? @Emoji.template else @Loading.template insertTpl: ':${name}:' data: ['loading'] callbacks: sorter: @DefaultOptions.sorter filter: @DefaultOptions.filter beforeInsert: @DefaultOptions.beforeInsert # Team Members @input.atwho at: '@' displayTpl: (value) => if value.username? @Members.template else @Loading.template insertTpl: '${atwho-at}${username}' searchKey: 'search' data: ['loading'] callbacks: sorter: @DefaultOptions.sorter filter: @DefaultOptions.filter beforeInsert: @DefaultOptions.beforeInsert beforeSave: (members) -> $.map members, (m) -> return m if not m.username? title = m.name title += " (#{m.count})" if m.count username: m.username title: sanitize(title) search: sanitize("#{m.username} #{m.name}") @input.atwho at: '#' alias: 'issues' searchKey: 'search' displayTpl: (value) => if value.title? @Issues.template else @Loading.template data: ['loading'] insertTpl: '${atwho-at}${id}' callbacks: sorter: @DefaultOptions.sorter filter: @DefaultOptions.filter beforeInsert: @DefaultOptions.beforeInsert beforeSave: (issues) -> $.map issues, (i) -> return i if not i.title? id: i.iid title: sanitize(i.title) search: "#{i.iid} #{i.title}" @input.atwho at: '%' alias: 'milestones' searchKey: 'search' displayTpl: (value) => if value.title? @Milestones.template else @Loading.template insertTpl: '${atwho-at}"${title}"' data: ['loading'] callbacks: beforeSave: (milestones) -> $.map milestones, (m) -> return m if not m.title? id: m.iid title: sanitize(m.title) search: "#{m.title}" @input.atwho at: '!' alias: 'mergerequests' searchKey: 'search' displayTpl: (value) => if value.title? @Issues.template else @Loading.template data: ['loading'] insertTpl: '${atwho-at}${id}' callbacks: sorter: @DefaultOptions.sorter filter: @DefaultOptions.filter beforeInsert: @DefaultOptions.beforeInsert beforeSave: (merges) -> $.map merges, (m) -> return m if not m.title? id: m.iid title: sanitize(m.title) search: "#{m.iid} #{m.title}" destroyAtWho: -> @input.atwho('destroy') fetchData: (dataSource) -> $.getJSON(dataSource) loadData: (data) -> @dataLoaded = true # load members @input.atwho 'load', '@', data.members # load issues @input.atwho 'load', 'issues', data.issues # load milestones @input.atwho 'load', 'milestones', data.milestones # load merge requests @input.atwho 'load', 'mergerequests', data.mergerequests # load emojis @input.atwho 'load', ':', data.emojis # This trigger at.js again # otherwise we would be stuck with loading until the user types $(':focus').trigger('keyup')