Browse Source

Refactoring of object organization selector.

Martin Edenhofer 8 years ago
parent
commit
873df9528a

+ 431 - 0
app/assets/javascripts/app/lib/app_post/_object_organization_autocompletion.coffee

@@ -0,0 +1,431 @@
+class App.ObjectOrganizationAutocompletion extends App.Controller
+  className: 'dropdown js-recipientDropdown'
+  events:
+    'hide.bs.dropdown .js-recipientDropdown': 'hideOrganizationMembers'
+    'click .js-organization':                 'showOrganizationMembers'
+    'click .js-back':                         'hideOrganizationMembers'
+    'click .js-object':                       'onObjectClick'
+    'click .js-objectNew':                    'newObject'
+    'focus .js-objectSelect':                 'onFocus'
+    'click .js-objectSelect':                 'stopPropagation'
+    'blur .js-objectSelect':                  'onBlur'
+    'click .form-control':                    'focusInput'
+    'click':                                  'stopPropagation'
+    'change .js-objectId':                    'executeCallback'
+    'click .js-remove':                       'removeThisToken'
+
+  elements:
+    '.recipientList':   'recipientList'
+    '.js-objectSelect': 'objectSelect'
+    '.js-objectId':     'objectId'
+    '.form-control':    'formControl'
+
+  templateObjectItem: 'generic/object_search/item_object'
+  templateObjectNew: 'generic/object_search/new_object'
+  templateOrganizationItem: 'generic/object_search/item_organization'
+  templateOrganizationItemMembers: 'generic/object_search/item_organization_members'
+
+  objectSingle: 'User'
+  objectIcon: 'user'
+  objectSingels: 'People'
+  objectCreate: 'Create new object'
+  referenceAttribute: 'member_ids'
+
+  constructor: (params) ->
+    super
+
+    @lazySearch = _.debounce(@searchObject, 200)
+
+    @key = Math.floor( Math.random() * 999999 ).toString()
+
+    if !@attribute.source
+      @attribute.source = "#{@apiPath}/search/user-organization"
+    @build()
+
+    # set current value
+    if @attribute.value and @callback
+      @callback(@attribute.value)
+
+  element: =>
+    @el
+
+  release: ->
+    $(window).off 'click.ObjectOrganizationAutocompletion'
+
+  open: =>
+    # prevent rebinding of keydown event
+    return if @el.hasClass 'open'
+
+    @el.addClass('open')
+    $(window).on 'click.ObjectOrganizationAutocompletion', @close
+    $(window).on 'keydown.ObjectOrganizationAutocompletion', @navigateByKeyboard
+
+  close: =>
+    $(window).off 'keydown.ObjectOrganizationAutocompletion'
+    @el.removeClass('open')
+
+    $(window).off 'click.ObjectOrganizationAutocompletion'
+
+  onFocus: =>
+    @formControl.addClass 'focus'
+    @open()
+
+  focusInput: =>
+    @objectSelect.focus() if not @formControl.hasClass 'focus'
+
+  onBlur: =>
+    selectObject = @objectSelect.val()
+    if _.isEmpty(selectObject)
+      @objectId.val('')
+      return
+    if @attribute.guess is true
+      currentObjectId = @objectId.val()
+      if _.isEmpty(currentObjectId) || currentObjectId.match(/^guess:/)
+        if !_.isEmpty(selectObject)
+          @objectId.val("guess:#{selectObject}")
+    @formControl.removeClass 'focus'
+
+  onObjectClick: (e) =>
+    objectId = $(e.currentTarget).data('object-id')
+    @selectObject(objectId)
+    @close()
+
+  selectObject: (objectId) =>
+    if @attribute.multiple and @objectId.val()
+      # add objectId to end of comma separated list
+      objectId = _.chain( @objectId.val().split(',') ).push(objectId).join(',').value()
+
+    @objectSelect.val('')
+    @objectId.val(objectId).trigger('change')
+
+  executeCallback: =>
+    # with @attribute.multiple this can be several objects ids.
+    # Only work with the last one since its the newest one
+    objectId = @objectId.val().split(',').pop()
+
+    return if !objectId
+    return if !App[@objectSingle].exists(objectId)
+    object = App[@objectSingle].find(objectId)
+    name = object.displayName()
+
+    if @attribute.multiple
+      # create token
+      @createToken name, objectId
+    else
+      if object.email
+        name += " <#{object.email}>"
+
+      @objectSelect.val(name)
+
+    if @callback
+      @callback(objectId)
+
+  createToken: (name, objectId) =>
+    @objectSelect.before App.view('generic/token')(
+      name: name
+      value: objectId
+    )
+
+  removeThisToken: (e) =>
+    @removeToken $(e.currentTarget).parents('.token')
+
+  removeToken: (which) =>
+    switch which
+      when 'last'
+        token = @$('.token').last()
+        return if not token.size()
+      else
+        token = which
+
+    # remove objectId from input
+    index = @$('.token').index(token)
+    ids = @objectId.val().split(',')
+    ids.splice(index, 1)
+    @objectId.val ids.join(',')
+
+    token.remove()
+
+  navigateByKeyboard: (e) =>
+    switch e.keyCode
+      # clean input on esc
+      when 27
+        # if org member selection is shown, go back to member list
+        if !@recipientList.hasClass('is-shown')
+          @hideOrganizationMembers()
+          return
+
+        # empty object selection and close
+        @objectSelect.val('').trigger('change')
+      # remove last token on backspace
+      when 8
+        if @objectSelect.val() is ''
+          @removeToken('last')
+      # close on tab
+      when 9 then @close()
+      # ignore left and right
+      when 37, 39 then return
+      # up / select upper item
+      when 38
+        e.preventDefault()
+        if @recipientList.hasClass('is-shown')
+          if @recipientList.find('li.is-active').length is 0
+            @recipientList.find('li').last().addClass('is-active')
+          else
+            if @recipientList.find('li.is-active').prev().length isnt 0
+              @recipientList.find('li.is-active').removeClass('is-active').prev().addClass('is-active')
+          return
+        recipientListOrgMemeber = @$('.recipientList-organizationMembers').not('.hide')
+        if recipientListOrgMemeber.not('.hide').find('li.is-active').length is 0
+          recipientListOrgMemeber.not('.hide').find('li').last().addClass('is-active')
+        else
+          if recipientListOrgMemeber.not('.hide').find('li.is-active').prev().length isnt 0
+            recipientListOrgMemeber.not('.hide').find('li.is-active').removeClass('is-active').prev().addClass('is-active')
+        return
+      # down / select lower item
+      when 40
+        e.preventDefault()
+        if @recipientList.hasClass('is-shown')
+          if @recipientList.find('li.is-active').length is 0
+            @recipientList.find('li').first().addClass('is-active')
+          else
+            if @recipientList.find('li.is-active').next().length isnt 0
+              @recipientList.find('li.is-active').removeClass('is-active').next().addClass('is-active')
+          return
+        recipientListOrgMemeber = @$('.recipientList-organizationMembers').not('.hide')
+        if recipientListOrgMemeber.not('.hide').find('li.is-active').length is 0
+          recipientListOrgMemeber.find('li').first().addClass('is-active')
+        else
+          if recipientListOrgMemeber.not('.hide').find('li.is-active').next().length isnt 0
+            recipientListOrgMemeber.not('.hide').find('li.is-active').removeClass('is-active').next().addClass('is-active')
+        return
+      # enter / take item
+      when 13
+        e.preventDefault()
+        e.stopPropagation()
+
+        # nav by org member selection
+        if !@recipientList.hasClass('is-shown')
+          recipientListOrganizationMembers = @$('.recipientList-organizationMembers').not('.hide')
+          if recipientListOrganizationMembers.find('.js-back.is-active').get(0)
+            @hideOrganizationMembers()
+            return
+          objectId = recipientListOrganizationMembers.find('li.is-active').data('object-id')
+          return if !objectId
+          @selectObject(objectId)
+          @close() if !@attribute.multiple
+          return
+
+        # nav by object list selection
+        objectId = @recipientList.find('li.is-active').data('object-id')
+        if objectId
+          if objectId is 'new'
+            @newObject()
+          else
+            @selectObject(objectId)
+            @close() if !@attribute.multiple
+          return
+
+        organizationId = @recipientList.find('li.is-active').data('organization-id')
+        return if !organizationId
+        @showOrganizationMembers(undefined, @recipientList.find('li.is-active'))
+
+
+  buildOrganizationItem: (organization) ->
+    objectCount = 0
+    if organization[@referenceAttribute]
+      objectCount = organization[@referenceAttribute].length
+    App.view(@templateOrganizationItem)(
+      organization: organization
+      objectSingels: @objectSingels
+      objectCount: objectCount
+    )
+
+  buildOrganizationMembers: (organization) =>
+    organizationMemebers = $( App.view(@templateOrganizationItemMembers)(
+      organization: organization
+    ) )
+    if organization[@referenceAttribute]
+      for objectId in organization[@referenceAttribute]
+        object = App[@objectSingle].fullLocal(objectId)
+        organizationMemebers.append(@buildObjectItem(object))
+
+  buildObjectItem: (object) =>
+    App.view(@templateObjectItem)(
+      object: object
+      icon: @objectIcon
+    )
+
+  buildObjectNew: =>
+    App.view(@templateObjectNew)(
+      objectCreate: @objectCreate
+    )
+
+  build: =>
+    tokens = ''
+    name = ''
+    value = ''
+
+    if @attribute.multiple && @attribute.value
+
+      # fallback for if the value is not an array
+      if typeof @attribute.value isnt 'object'
+        @attribute.value = [@attribute.value]
+      value = @attribute.value.join ','
+
+      # create tokens
+      for objectId in @attribute.value
+        if App[@objectSingle].exists objectId
+          tokens += App.view('generic/token')(
+            name: App[@objectSingle].find(objectId).displayName()
+            value: objectId
+          )
+        else
+          @log 'objectId doesn\'t exist', objectId
+    else
+      value = @attribute.value
+      if value
+        if App[@objectSingle].exists(value)
+          object = App[@objectSingle].find(value)
+          name = object.displayName()
+          if object.email
+            name += " <#{object.email}>"
+        else if @params && @params["#{@attribute.name}_completion"]
+          name = @params["#{@attribute.name}_completion"]
+        else
+          @log 'objectId doesn\'t exist', value
+
+    @html App.view('generic/object_search/input')(
+      attribute: @attribute
+      value: value
+      tokens: tokens
+      name: name
+    )
+
+    if !@attribute.disableCreateObject
+      @recipientList.append(@buildObjectNew())
+
+    # start search
+    @searchTerm = ''
+
+    @objectSelect.on 'keyup', @onKeyUp
+
+  onKeyUp: (e) =>
+    query = $(e.target).val().trim()
+    return if @searchTerm is query
+    @searchTerm = query
+
+    @hideOrganizationMembers()
+
+    # hide dropdown
+    if !query
+      @emptyResultList()
+
+      if !@attribute.disableCreateObject
+        @recipientList.append(@buildObjectNew())
+
+    # show dropdown
+    if query && ( !@attribute.minLengt || @attribute.minLengt <= query.length )
+      @lazySearch(query)
+
+  searchObject: (query) =>
+    @ajax(
+      id:    "searchObject#{@key}"
+      type:  'GET'
+      url:   @attribute.source
+      data:
+        query: query
+      processData: true
+      success: (data, status, xhr) =>
+        @emptyResultList()
+
+        # load assets
+        App.Collection.loadAssets(data.assets)
+
+        # build markup
+        for item in data.result
+
+          # organization
+          if item.type is 'Organization'
+            organization = App.Organization.fullLocal(item.id)
+            @recipientList.append(@buildOrganizationItem(organization))
+
+            # objectss of organization
+            if organization[@referenceAttribute]
+              @$('.dropdown-menu').append(@buildOrganizationMembers(organization))
+
+          # objectss
+          if item.type is @objectSingle
+            object = App[@objectSingle].fullLocal(item.id)
+            @recipientList.append(@buildObjectItem(object))
+
+        if !@attribute.disableCreateObject
+          @recipientList.append(@buildObjectNew())
+
+        @recipientList.find('.js-object').first().addClass('is-active')
+    )
+
+  emptyResultList: =>
+    @recipientList.empty()
+    @$('.recipientList-organizationMembers').remove()
+
+  showOrganizationMembers: (e,listEntry) =>
+    if e
+      e.stopPropagation()
+      listEntry = $(e.currentTarget)
+
+    organizationId = listEntry.data('organization-id')
+
+    @organizationList = @$("[organization-id=#{ organizationId }]")
+
+    return if !@organizationList.get(0)
+
+    @recipientList.removeClass('is-shown')
+    @$('.recipientList-organizationMembers').addClass('is-shown')
+
+    # move organization-list to the right and slide it in
+    $.Velocity.hook(@organizationList, 'translateX', '100%')
+    @organizationList.removeClass('hide')
+
+    @organizationList.velocity
+      properties:
+        translateX: 0
+      options:
+        speed: 300
+
+    # fade out list
+    @recipientList.velocity
+      properties:
+        translateX: '-100%'
+      options:
+        speed: 300
+        complete: => @recipientList.height(@organizationList.height())
+
+  hideOrganizationMembers: (e) =>
+    e && e.stopPropagation()
+
+    @recipientList.addClass('is-shown')
+    @$('.recipientList-organizationMembers').removeClass('is-shown')
+
+    return if !@organizationList
+
+    # fade list back in
+    @recipientList.velocity
+      properties:
+        translateX: 0
+      options:
+        speed: 300
+
+    # reset list height
+    @recipientList.height('')
+
+    # slide out organization-list and hide it
+    @organizationList.velocity
+      properties:
+        translateX: '100%'
+      options:
+        speed: 300
+        complete: => @organizationList.addClass('hide')
+
+  newObject: (e) ->
+    if e
+      e.preventDefault()

+ 8 - 409
app/assets/javascripts/app/lib/app_post/user_organization_autocompletion.coffee

@@ -1,412 +1,11 @@
-class App.UserOrganizationAutocompletion extends App.Controller
-  className: 'dropdown js-recipientDropdown'
-  events:
-    'hide.bs.dropdown .js-recipientDropdown': 'hideOrganizationMembers'
-    'click .js-organization':                 'showOrganizationMembers'
-    'click .js-back':                         'hideOrganizationMembers'
-    'click .js-user':                         'onUserClick'
-    'click .js-userNew':                      'newUser'
-    'focus .js-userSelect':                   'onFocus'
-    'click .js-userSelect':                   'stopPropagation'
-    'blur .js-userSelect':                    'onBlur'
-    'click .form-control':                    'focusInput'
-    'click':                                  'stopPropagation'
-    'change .js-userId':                      'executeCallback'
-    'click .js-remove':                       'removeThisToken'
-
-  elements:
-    '.recipientList': 'recipientList'
-    '.js-userSelect': 'userSelect'
-    '.js-userId': 'userId'
-    '.form-control': 'formControl'
-
-  constructor: (params) ->
-    super
-
-    @lazySearch = _.debounce(@searchUser, 200)
-
-    @key = Math.floor( Math.random() * 999999 ).toString()
-
-    if !@attribute.source
-      @attribute.source = "#{@apiPath}/search/user-organization"
-    @build()
-
-    # set current value
-    if @attribute.value and @callback
-      @callback(@attribute.value)
-
-  element: =>
-    @el
-
-  release: ->
-    $(window).off 'click.UserOrganizationAutocompletion'
-
-  open: =>
-    # prevent rebinding of keydown event
-    return if @el.hasClass 'open'
-
-    @el.addClass('open')
-    $(window).on 'click.UserOrganizationAutocompletion', @close
-    $(window).on 'keydown.UserOrganizationAutocompletion', @navigateByKeyboard
-
-  close: =>
-    $(window).off 'keydown.UserOrganizationAutocompletion'
-    @el.removeClass('open')
-
-    $(window).off 'click.UserOrganizationAutocompletion'
-
-  onFocus: =>
-    @formControl.addClass 'focus'
-    @open()
-
-  focusInput: =>
-    @userSelect.focus() if not @formControl.hasClass 'focus'
-
-  onBlur: =>
-    selectUser = @userSelect.val()
-    if _.isEmpty(selectUser)
-      @userId.val('')
-      return
-    if @attribute.guess is true
-      currentUserId = @userId.val()
-      if _.isEmpty(currentUserId) || currentUserId.match(/^guess:/)
-        if !_.isEmpty(selectUser)
-          @userId.val("guess:#{selectUser}")
-    @formControl.removeClass 'focus'
-
-  onUserClick: (e) =>
-    userId = $(e.currentTarget).data('user-id')
-    @selectUser(userId)
-    @close()
-
-  selectUser: (userId) =>
-    if @attribute.multiple and @userId.val()
-      # add userId to end of comma separated list
-      userId = _.chain( @userId.val().split(',') ).push(userId).join(',').value()
-
-    @userSelect.val('')
-    @userId.val(userId).trigger('change')
-
-  executeCallback: =>
-    # with @attribute.multiple this can be several user ids.
-    # Only work with the last one since its the newest one
-    userId = @userId.val().split(',').pop()
-
-    return if !userId
-    return if !App.User.exists(userId)
-    user = App.User.find(userId)
-    name = user.displayName()
-
-    if @attribute.multiple
-      # create token
-      @createToken name, userId
-    else
-      if user.email
-        name += " <#{user.email}>"
-
-      @userSelect.val(name)
-
-    if @callback
-      @callback(userId)
-
-  createToken: (name, userId) =>
-    @userSelect.before App.view('generic/token')(
-      name: name
-      value: userId
-    )
-
-  removeThisToken: (e) =>
-    @removeToken $(e.currentTarget).parents('.token')
-
-  removeToken: (which) =>
-    switch which
-      when 'last'
-        token = @$('.token').last()
-        return if not token.size()
-      else
-        token = which
-
-    # remove userId from input
-    index = @$('.token').index(token)
-    ids = @userId.val().split(',')
-    ids.splice(index, 1)
-    @userId.val ids.join(',')
-
-    token.remove()
-
-  navigateByKeyboard: (e) =>
-    switch e.keyCode
-      # clean input on esc
-      when 27
-        # if org member selection is shown, go back to member list
-        if !@recipientList.hasClass('is-shown')
-          @hideOrganizationMembers()
-          return
-
-        # empty user selection and close
-        @userSelect.val('').trigger('change')
-      # remove last token on backspace
-      when 8
-        if @userSelect.val() is ''
-          @removeToken('last')
-      # close on tab
-      when 9 then @close()
-      # ignore left and right
-      when 37, 39 then return
-      # up / select upper item
-      when 38
-        e.preventDefault()
-        if @recipientList.hasClass('is-shown')
-          if @recipientList.find('li.is-active').length is 0
-            @recipientList.find('li').last().addClass('is-active')
-          else
-            if @recipientList.find('li.is-active').prev().length isnt 0
-              @recipientList.find('li.is-active').removeClass('is-active').prev().addClass('is-active')
-          return
-        recipientListOrgMemeber = @$('.recipientList-organizationMembers').not('.hide')
-        if recipientListOrgMemeber.not('.hide').find('li.is-active').length is 0
-          recipientListOrgMemeber.not('.hide').find('li').last().addClass('is-active')
-        else
-          if recipientListOrgMemeber.not('.hide').find('li.is-active').prev().length isnt 0
-            recipientListOrgMemeber.not('.hide').find('li.is-active').removeClass('is-active').prev().addClass('is-active')
-        return
-      # down / select lower item
-      when 40
-        e.preventDefault()
-        if @recipientList.hasClass('is-shown')
-          if @recipientList.find('li.is-active').length is 0
-            @recipientList.find('li').first().addClass('is-active')
-          else
-            if @recipientList.find('li.is-active').next().length isnt 0
-              @recipientList.find('li.is-active').removeClass('is-active').next().addClass('is-active')
-          return
-        recipientListOrgMemeber = @$('.recipientList-organizationMembers').not('.hide')
-        if recipientListOrgMemeber.not('.hide').find('li.is-active').length is 0
-          recipientListOrgMemeber.find('li').first().addClass('is-active')
-        else
-          if recipientListOrgMemeber.not('.hide').find('li.is-active').next().length isnt 0
-            recipientListOrgMemeber.not('.hide').find('li.is-active').removeClass('is-active').next().addClass('is-active')
-        return
-      # enter / take item
-      when 13
-        e.preventDefault()
-        e.stopPropagation()
-
-        # nav by org member selection
-        if !@recipientList.hasClass('is-shown')
-          recipientListOrganizationMembers = @$('.recipientList-organizationMembers').not('.hide')
-          if recipientListOrganizationMembers.find('.js-back.is-active').get(0)
-            @hideOrganizationMembers()
-            return
-          userId = recipientListOrganizationMembers.find('li.is-active').data('user-id')
-          return if !userId
-          @selectUser(userId)
-          @close() if !@attribute.multiple
-          return
-
-        # nav by user list selection
-        userId = @recipientList.find('li.is-active').data('user-id')
-        if userId
-          if userId is 'new'
-            @newUser()
-          else
-            @selectUser(userId)
-            @close() if !@attribute.multiple
-          return
-
-        organizationId = @recipientList.find('li.is-active').data('organization-id')
-        return if !organizationId
-        @showOrganizationMembers(undefined, @recipientList.find('li.is-active'))
-
-
-  buildOrganizationItem: (organization) ->
-    App.view('generic/user_search/item_organization')(
-      organization: organization
-    )
-
-  buildOrganizationMembers: (organization) =>
-    organizationMemebers = $( App.view('generic/user_search/item_organization_members')(
-      organization: organization
-    ) )
-    for userId in organization.member_ids
-      user = App.User.fullLocal(userId)
-      organizationMemebers.append(@buildUserItem(user))
-
-  buildUserItem: (user) ->
-    App.view('generic/user_search/item_user')(
-      user: user
-    )
-
-  buildUserNew: ->
-    App.view('generic/user_search/new_user')()
-
-  build: =>
-    tokens = ''
-    name = ''
-    value = ''
-
-    if @attribute.multiple && @attribute.value
-
-      # fallback for if the value is not an array
-      if typeof @attribute.value isnt 'object'
-        @attribute.value = [@attribute.value]
-      value = @attribute.value.join ','
-
-      # create tokens
-      for userId in @attribute.value
-        if App.User.exists userId
-          tokens += App.view('generic/token')(
-            name: App.User.find(userId).displayName()
-            value: userId
-          )
-        else
-          @log 'userId doesn\'t exist', userId
-    else
-      value = @attribute.value
-      if value
-        if App.User.exists value
-          user = App.User.find(value)
-          name = user.displayName()
-          if user.email
-            name += " <#{user.email}>"
-        else if @params && @params["#{@attribute.name}_completion"]
-          name = @params["#{@attribute.name}_completion"]
-        else
-          @log 'userId doesn\'t exist', value
-
-    @html App.view('generic/user_search/input')(
-      attribute: @attribute
-      value: value
-      tokens: tokens
-      name: name
-    )
-
-    if !@attribute.disableCreateUser
-      @recipientList.append(@buildUserNew())
-
-    # start search
-    @searchTerm = ''
-
-    @userSelect.on 'keyup', @onKeyUp
-
-  onKeyUp: (e) =>
-    query = $(e.target).val().trim()
-    return if @searchTerm is query
-    @searchTerm = query
-
-    @hideOrganizationMembers()
-
-    # hide dropdown
-    if !query
-      @emptyResultList()
-
-      if !@attribute.disableCreateUser
-        @recipientList.append(@buildUserNew())
-
-    # show dropdown
-    if query && ( !@attribute.minLengt || @attribute.minLengt <= query.length )
-      @lazySearch(query)
-
-  searchUser: (query) =>
-    @ajax(
-      id:    "searchUser#{@key}"
-      type:  'GET'
-      url:   @attribute.source
-      data:
-        query: query
-      processData: true
-      success: (data, status, xhr) =>
-        @emptyResultList()
-
-        # load assets
-        App.Collection.loadAssets(data.assets)
-
-        # build markup
-        for item in data.result
-
-          # organization
-          if item.type is 'Organization'
-            organization = App.Organization.fullLocal(item.id)
-            @recipientList.append(@buildOrganizationItem(organization))
-
-            # users of organization
-            if organization.member_ids
-              @$('.dropdown-menu').append(@buildOrganizationMembers(organization))
-
-          # users
-          if item.type is 'User'
-            user = App.User.fullLocal(item.id)
-            @recipientList.append(@buildUserItem(user))
-
-        if !@attribute.disableCreateUser
-          @recipientList.append(@buildUserNew())
-
-        @recipientList.find('.js-user').first().addClass('is-active')
-    )
-
-  emptyResultList: =>
-    @recipientList.empty()
-    @$('.recipientList-organizationMembers').remove()
-
-  showOrganizationMembers: (e,listEntry) =>
-    if e
-      e.stopPropagation()
-      listEntry = $(e.currentTarget)
-
-    organizationId = listEntry.data('organization-id')
-
-    @organizationList = @$("[organization-id=#{ organizationId }]")
-
-    return if !@organizationList.get(0)
-
-    @recipientList.removeClass('is-shown')
-    @$('.recipientList-organizationMembers').addClass('is-shown')
-
-    # move organization-list to the right and slide it in
-    $.Velocity.hook(@organizationList, 'translateX', '100%')
-    @organizationList.removeClass('hide')
-
-    @organizationList.velocity
-      properties:
-        translateX: 0
-      options:
-        speed: 300
-
-    # fade out list
-    @recipientList.velocity
-      properties:
-        translateX: '-100%'
-      options:
-        speed: 300
-        complete: => @recipientList.height(@organizationList.height())
-
-  hideOrganizationMembers: (e) =>
-    e && e.stopPropagation()
-
-    @recipientList.addClass('is-shown')
-    @$('.recipientList-organizationMembers').removeClass('is-shown')
-
-    return if !@organizationList
-
-    # fade list back in
-    @recipientList.velocity
-      properties:
-        translateX: 0
-      options:
-        speed: 300
-
-    # reset list height
-    @recipientList.height('')
-
-    # slide out organization-list and hide it
-    @organizationList.velocity
-      properties:
-        translateX: '100%'
-      options:
-        speed: 300
-        complete: => @organizationList.addClass('hide')
-
-  newUser: (e) =>
+class App.UserOrganizationAutocompletion extends App.ObjectOrganizationAutocompletion
+  objectSingle: 'User'
+  objectIcon: 'user'
+  objectSingels: 'People'
+  objectCreate: 'Create new Customer'
+  referenceAttribute: 'member_ids'
+
+  newObject: (e) =>
     if e
       e.preventDefault()
     new UserNew(

+ 1 - 1
app/assets/javascripts/app/views/generic/user_search/item_organization.jst.eco → app/assets/javascripts/app/views/generic/object_search/item_organization.jst.eco

@@ -4,7 +4,7 @@
   </div>
   <div class="recipientList-name">
     <%= @organization.displayName() %>
-    <span class="recipientList-detail">- <%= @organization.member_ids.length %> <%- @T('People') %></span>
+    <span class="recipientList-detail">- <%= @objectCount %> <%- @T(@objectSingels) %></span>
   </div>
   <%- @Icon('arrow-right', 'recipientList-arrow') %>
 </li>

+ 0 - 0
app/assets/javascripts/app/views/generic/user_search/item_organization_members.jst.eco → app/assets/javascripts/app/views/generic/object_search/item_organization_members.jst.eco


+ 2 - 2
app/assets/javascripts/app/views/generic/user_search/new_user.jst.eco → app/assets/javascripts/app/views/generic/object_search/new_object.jst.eco

@@ -1,8 +1,8 @@
-<li class="recipientList-entry recipientList--new js-userNew" data-user-id="new">
+<li class="recipientList-entry recipientList--new js-objectNew" data-object-id="new">
   <div class="recipientList-iconSpacer">
     <%- @Icon('plus', 'recipientList-icon') %>
   </div>
   <div class="recipientList-name">
-    <%- @T('Create new Customer') %>
+    <%- @T(@objectCreate) %>
   </div>
 </li>

+ 0 - 12
app/assets/javascripts/app/views/generic/user_search/input.jst.eco

@@ -1,12 +0,0 @@
-<div class="tokenfield form-control u-positionOrigin">
-  <input class="js-userId" type="hidden" value="<%= @value %>" name="<%- @attribute.name %>" tabindex="-1">
-  <% if @attribute.multiple: %>
-    <%- @tokens %>
-  <% end %>
-  <input name="<%- @attribute.name %>_completion" class="user-select token-input js-userSelect" autocapitalize="off" placeholder="<%- @attribute.placeholder %>" autocomplete="off" role="textbox" aria-autocomplete="list" value="<%= @name %>" aria-haspopup="true">
-  <% if @attribute.disableCreateUser isnt true: %><%- @Icon('arrow-down', 'dropdown-arrow') %><% end %>
-</div>
-
-<div class="dropdown-menu" aria-labelledby="customer_id">
-  <ul class="recipientList" role="menu"></ul>
-</div>

+ 0 - 11
app/assets/javascripts/app/views/generic/user_search/item_user.jst.eco

@@ -1,11 +0,0 @@
-<li class="recipientList-entry js-user" data-user-id="<%= @user.id %>">
-  <div class="recipientList-iconSpacer">
-    <%- @Icon('user', 'recipientList-icon') %>
-  </div>
-  <div class="recipientList-name">
-    <%= @user.displayName() %>
-    <% if @user.organization: %>
-      <span class="recipientList-detail">- <%= @user.organization.displayName() %></span>
-    <% end %>
-  </div>
-</li>

+ 3 - 3
test/browser_test_helper.rb

@@ -1564,7 +1564,7 @@ wait untill text in selector disabppears
     sleep 2.5
 
     element.send_keys(:enter)
-    #instance.find_elements(css: params[:css] + ' .recipientList-entry.js-user.is-active')[0].click
+    #instance.find_elements(css: params[:css] + ' .recipientList-entry.js-object.is-active')[0].click
     sleep 0.4
     assert(true, 'ticket_customer_select')
   end
@@ -1928,7 +1928,7 @@ wait untill text in selector disabppears
       # ff issue, sometimes enter event gets dropped
       # take user manually
       if instance.find_elements(css: '.content.active .newTicket .js-recipientDropdown.open')[0]
-        instance.find_elements(css: '.content.active .newTicket .recipientList-entry.js-user.is-active')[0].click
+        instance.find_elements(css: '.content.active .newTicket .recipientList-entry.js-object.is-active')[0].click
         sleep 0.4
       end
     end
@@ -2092,7 +2092,7 @@ wait untill text in selector disabppears
       sleep 2.5
 
       element.send_keys(:enter)
-      #instance.find_elements(css: '.modal .user_autocompletion .recipientList-entry.js-user.is-active')[0].click
+      #instance.find_elements(css: '.modal .user_autocompletion .recipientList-entry.js-object.is-active')[0].click
       sleep 0.2
 
       click(browser: instance, css: '.modal .js-submit')