mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Add modules hook for contacts and support groups in auto complete
This commit is contained in:
parent
78c5741d06
commit
c4e4f2c77a
5 changed files with 70 additions and 16 deletions
|
@ -2,6 +2,7 @@ AuthenticationController = require "../Authentication/AuthenticationController"
|
|||
ContactManager = require "./ContactManager"
|
||||
UserGetter = require "../User/UserGetter"
|
||||
logger = require "logger-sharelatex"
|
||||
Modules = require "../../infrastructure/Modules"
|
||||
|
||||
module.exports = ContactsController =
|
||||
getContacts: (req, res, next) ->
|
||||
|
@ -24,9 +25,13 @@ module.exports = ContactsController =
|
|||
contacts = contacts.filter (c) -> !c.holdingAccount
|
||||
|
||||
contacts = contacts.map(ContactsController._formatContact)
|
||||
res.send({
|
||||
contacts: contacts
|
||||
})
|
||||
|
||||
Modules.hooks.fire "getContacts", user_id, contacts, (error, additional_contacts) ->
|
||||
return next(error) if error?
|
||||
contacts = contacts.concat(additional_contacts...)
|
||||
res.send({
|
||||
contacts: contacts
|
||||
})
|
||||
|
||||
_formatContact: (contact) ->
|
||||
return {
|
||||
|
@ -34,4 +39,5 @@ module.exports = ContactsController =
|
|||
email: contact.email
|
||||
first_name: contact.first_name
|
||||
last_name: contact.last_name
|
||||
type: "user"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
fs = require "fs"
|
||||
Path = require "path"
|
||||
jade = require "jade"
|
||||
async = require "async"
|
||||
|
||||
MODULE_BASE_PATH = Path.resolve(__dirname + "/../../../modules")
|
||||
|
||||
|
@ -12,6 +13,7 @@ module.exports = Modules =
|
|||
loadedModule = require(Path.join(MODULE_BASE_PATH, moduleName, "index"))
|
||||
loadedModule.name = moduleName
|
||||
@modules.push loadedModule
|
||||
Modules.attachHooks()
|
||||
|
||||
applyRouter: (webRouter, apiRouter) ->
|
||||
for module in @modules
|
||||
|
@ -36,4 +38,25 @@ module.exports = Modules =
|
|||
moduleIncludesAvailable: (view) ->
|
||||
return (Modules.viewIncludes[view] or []).length > 0
|
||||
|
||||
attachHooks: () ->
|
||||
for module in @modules
|
||||
if module.hooks?
|
||||
for hook, method of module.hooks
|
||||
Modules.hooks.attach hook, method
|
||||
|
||||
hooks:
|
||||
_hooks: {}
|
||||
attach: (name, method) ->
|
||||
console.log "attaching hook", name, method
|
||||
@_hooks[name] ?= []
|
||||
@_hooks[name].push method
|
||||
|
||||
fire: (name, args..., callback) ->
|
||||
methods = @_hooks[name] or []
|
||||
call_methods = methods.map (method) ->
|
||||
return (cb) -> method(args..., cb)
|
||||
async.series call_methods, (error, results) ->
|
||||
return callback(error) if error?
|
||||
return callback null, results
|
||||
|
||||
Modules.loadModules()
|
|
@ -52,7 +52,7 @@ script(type='text/ng-template', id='shareProjectModalTemplate')
|
|||
placeholder="joe@example.com, sue@example.com, ..."
|
||||
ng-model="inputs.contacts"
|
||||
focus-on="open"
|
||||
display-property="email"
|
||||
display-property="display"
|
||||
key-property="id"
|
||||
add-on-paste="true"
|
||||
)
|
||||
|
@ -145,8 +145,13 @@ script(type="text/ng-template", id="shareTagTemplate")
|
|||
|
||||
script(type="text/ng-template", id="shareAutocompleteTemplate")
|
||||
.autocomplete-template
|
||||
i.fa(ng-class="{'fa-user': data.type == 'user', 'fa-group': data.type == 'group'}")
|
||||
|
|
||||
span(ng-bind-html="$highlight(data.email)")
|
||||
div.subdued.small(ng-show="data.name", ng-bind-html="$highlight(data.name)")
|
||||
div.subdued.small(ng-show="data.memberCount") {{ data.memberCount }} members
|
||||
div(ng-if="data.type == 'user'")
|
||||
i.fa.fa-user
|
||||
|
|
||||
span(ng-bind-html="$highlight(data.email)")
|
||||
div.subdued.small(ng-show="data.name", ng-bind-html="$highlight(data.name)")
|
||||
div(ng-if="data.type == 'group'")
|
||||
i.fa.fa-group
|
||||
|
|
||||
span(ng-bind-html="$highlight(data.name)")
|
||||
div.subdued.small(ng-show="data.member_count") {{ data.memberCount }} members
|
||||
|
|
|
@ -29,12 +29,23 @@ define [
|
|||
do loadAutocompleteUsers = () ->
|
||||
$http.get "/user/contacts"
|
||||
.success (data) ->
|
||||
console.log "Got contacts", data
|
||||
$scope.autocompleteContacts = data.contacts or []
|
||||
for contact in $scope.autocompleteContacts
|
||||
if contact.type == "user"
|
||||
if contact.last_name == "" and contact.first_name = contact.email.split("@")[0]
|
||||
# User has not set their proper name so use email as canonical display property
|
||||
contact.name = ""
|
||||
contact.display = contact.email
|
||||
else
|
||||
contact.name = "#{contact.first_name} #{contact.last_name}"
|
||||
contact.display = "#{contact.name} <#{contact.email}>"
|
||||
else
|
||||
# Must be a group
|
||||
contact.display = contact.name
|
||||
|
||||
$scope.filterAutocompleteUsers = ($query) ->
|
||||
return $scope.autocompleteContacts.filter (user) ->
|
||||
for text in [user.name, user.email]
|
||||
return $scope.autocompleteContacts.filter (contact) ->
|
||||
for text in [contact.name, contact.email]
|
||||
if text?.toLowerCase().indexOf($query.toLowerCase()) > -1
|
||||
return true
|
||||
return false
|
||||
|
@ -43,7 +54,9 @@ define [
|
|||
$timeout -> # Give email list a chance to update
|
||||
return if $scope.inputs.contacts.length == 0
|
||||
|
||||
emails = $scope.inputs.contacts.map (contact) -> contact.email
|
||||
console.warn "Ignoring groups for now"
|
||||
emails = $scope.inputs.contacts.filter (contact) -> contact.type == "user"
|
||||
emails = emails.map (contact) -> contact.email
|
||||
$scope.inputs.contacts = []
|
||||
$scope.state.error = null
|
||||
$scope.state.inflight = true
|
||||
|
|
|
@ -13,6 +13,7 @@ describe "ContactController", ->
|
|||
"../User/UserGetter": @UserGetter = {}
|
||||
"./ContactManager": @ContactManager = {}
|
||||
"../Authentication/AuthenticationController": @AuthenticationController = {}
|
||||
"../../infrastructure/Modules": @Modules = { hooks: {} }
|
||||
|
||||
@next = sinon.stub()
|
||||
@req = {}
|
||||
|
@ -32,6 +33,7 @@ describe "ContactController", ->
|
|||
@AuthenticationController.getLoggedInUserId = sinon.stub().callsArgWith(1, null, @user_id)
|
||||
@ContactManager.getContactIds = sinon.stub().callsArgWith(2, null, @contact_ids)
|
||||
@UserGetter.getUsers = sinon.stub().callsArgWith(2, null, @contacts)
|
||||
@Modules.hooks.fire = sinon.stub().callsArg(3)
|
||||
|
||||
@ContactController.getContacts @req, @res, @next
|
||||
|
||||
|
@ -50,8 +52,13 @@ describe "ContactController", ->
|
|||
.calledWith(@contact_ids, { email: 1, first_name: 1, last_name: 1, holdingAccount: 1 })
|
||||
.should.equal true
|
||||
|
||||
it "should fire the getContact module hook", ->
|
||||
@Modules.hooks.fire
|
||||
.calledWith("getContacts", @user_id)
|
||||
.should.equal true
|
||||
|
||||
it "should return a formatted list of contacts in contact list order, without holding accounts", ->
|
||||
@res.send.args[0][0].contacts.should.deep.equal [
|
||||
{ id: "contact-1", email: "joe@example.com", first_name: "Joe", last_name: "Example" }
|
||||
{ id: "contact-3", email: "jim@example.com", first_name: "Jim", last_name: "Example" }
|
||||
{ id: "contact-1", email: "joe@example.com", first_name: "Joe", last_name: "Example", type: "user" }
|
||||
{ id: "contact-3", email: "jim@example.com", first_name: "Jim", last_name: "Example", type: "user" }
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue