Add modules hook for contacts and support groups in auto complete

This commit is contained in:
James Allen 2015-10-08 18:17:53 +01:00
parent 78c5741d06
commit c4e4f2c77a
5 changed files with 70 additions and 16 deletions

View file

@ -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,6 +25,10 @@ module.exports = ContactsController =
contacts = contacts.filter (c) -> !c.holdingAccount
contacts = contacts.map(ContactsController._formatContact)
Modules.hooks.fire "getContacts", user_id, contacts, (error, additional_contacts) ->
return next(error) if error?
contacts = contacts.concat(additional_contacts...)
res.send({
contacts: contacts
})
@ -34,4 +39,5 @@ module.exports = ContactsController =
email: contact.email
first_name: contact.first_name
last_name: contact.last_name
type: "user"
}

View file

@ -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()

View file

@ -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'}")
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.subdued.small(ng-show="data.memberCount") {{ data.memberCount }} members
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

View file

@ -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

View file

@ -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" }
]