Browse Source

Init version of object manager.

Martin Edenhofer 8 years ago
parent
commit
1248f4080b

+ 17 - 8
app/assets/javascripts/app/controllers/_application_controller_form.coffee

@@ -204,6 +204,8 @@ class App.ControllerForm extends App.Controller
       attribute.autofocus = 'autofocus'
 
     # set required option
+    if attribute.required is true
+      attribute.null = false
     if !attribute.null
       attribute.required = 'required'
     else
@@ -231,7 +233,7 @@ class App.ControllerForm extends App.Controller
       # check if we have a references
       parts = attribute.name.split '::'
       if parts[0] && parts[1]
-        if @params[ parts[0] ] && @params[ parts[0] ][ parts[1] ]
+        if @params[ parts[0] ] && parts[1] of @params[ parts[0] ]
           attribute.value = @params[ parts[0] ][ parts[1] ]
 
       # set params value to default
@@ -480,15 +482,22 @@ class App.ControllerForm extends App.Controller
     for key of param
       parts = key.split '::'
       if parts[0] && parts[1]
-        if !(parts[0] of inputSelectObject)
+        if parts[1] && !inputSelectObject[ parts[0] ]
           inputSelectObject[ parts[0] ] = {}
-        if !parts[2]
-          inputSelectObject[ parts[0] ][ parts[1] ] = param[ key ]
-        else
-          if !(parts[1] of inputSelectObject[ parts[0] ])
-            inputSelectObject[ parts[0] ][ parts[1] ] = {}
+        if parts[2] && !inputSelectObject[ parts[0] ][ parts[1] ]
+          inputSelectObject[ parts[0] ][ parts[1] ] = {}
+        if parts[3] && !inputSelectObject[ parts[0] ][ parts[1] ][ parts[2] ]
+          inputSelectObject[ parts[0] ][ parts[1] ][ parts[2] ] = {}
+
+        if parts[3]
+          inputSelectObject[ parts[0] ][ parts[1] ][ parts[2] ][ parts[3] ] = param[ key ]
+          delete param[ key ]
+        else if parts[2]
           inputSelectObject[ parts[0] ][ parts[1] ][ parts[2] ] = param[ key ]
-        delete param[ key ]
+          delete param[ key ]
+        else if parts[1]
+          inputSelectObject[ parts[0] ][ parts[1] ] = param[ key ]
+          delete param[ key ]
 
     # set new object params
     for key of inputSelectObject

+ 0 - 1
app/assets/javascripts/app/controllers/_dashboard/first_steps.coffee

@@ -40,7 +40,6 @@ class App.DashboardFirstSteps extends App.Controller
       #container: @el.closest('.content')
       head: 'Invite Colleagues'
       screen: 'invite_agent'
-      role: 'Agent'
     )
 
   inviteCustomer: (e) ->

+ 1 - 1
app/assets/javascripts/app/controllers/_ui_element/active.coffee

@@ -4,7 +4,7 @@ class App.UiElement.active extends App.UiElement.ApplicationUiElement
 
     # set attributes
     attribute.null = false
-    attribute.translation = true
+    attribute.translate = true
 
     # build options list
     attribute.options = [

+ 1 - 0
app/assets/javascripts/app/controllers/_ui_element/boolean.coffee

@@ -8,6 +8,7 @@ class App.UiElement.boolean extends App.UiElement.ApplicationUiElement
         { name: 'yes', value: true }
         { name: 'no', value: false }
       ]
+      attribute.translate = true
 
     # set data type
     if attribute.name

+ 304 - 0
app/assets/javascripts/app/controllers/_ui_element/object_manager_attribute.coffee

@@ -0,0 +1,304 @@
+
+# coffeelint: disable=camel_case_classes
+class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUiElement
+  @render: (attribute, params = {}) ->
+    item = $(App.view('object_manager/attribute')(attribute: attribute))
+
+    updateDataMap = (localParams, localAttribute, localAttributes, localClassname, localForm, localA) =>
+      localItem = localForm.closest('.js-data')
+      values = []
+      values = {a: 123, b: 'aaa'}
+      element = $(App.view("object_manager/attribute/#{localParams.data_type}")(
+        attribute: attribute
+        values: values
+      ))
+      @[localParams.data_type](element, localParams, params)
+      localItem.find('.js-dataMap').html(element)
+      localItem.find('.js-dataScreens').html(@dataScreens(attribute, localParams, params))
+
+    options =
+      datetime: 'Datetime'
+      date: 'Date'
+      input: 'Text'
+    #  select: 'Select'
+    #  boolean: 'Boolean'
+    #  integer: 'Integer'
+    #  autocompletion: 'Autocompletion (AJAX remote URL)'
+
+    configureAttributes = [
+      { name: attribute.name, display: '', tag: 'select', null: false, options: options, translate: true, default: 'input', disabled: attribute.disabled },
+    ]
+    dataType = new App.ControllerForm(
+      model:
+        configure_attributes: configureAttributes
+      noFieldset: true
+      handlers: [
+        updateDataMap,
+      ]
+      params: params
+    )
+    item.find('.js-dataType').html(dataType.form)
+
+    item
+
+  @dataScreens: (attribute, localParams, params) ->
+    object = params.object
+    objects =
+      Ticket:
+        Customer:
+          create:
+            shown: true
+            required: false
+          edit:
+            shown: true
+            required: false
+        Agent:
+          create_bottom:
+            show: true
+            required: false
+          edit:
+            shown: true
+            required: false
+      User:
+        Customer:
+          create:
+            shown: true
+            required: false
+          view:
+            shown: true
+          signup:
+            shown: false
+            required: false
+        Agent:
+          create:
+            shown: true
+            required: false
+          edit:
+            shown: true
+            required: false
+          view:
+            shown: true
+          invite_customer:
+            show: false
+            required: false
+        Admin:
+          create:
+            shown: true
+            required: false
+          edit:
+            shown: true
+            required: false
+          view:
+            shown: true
+          invite_agent:
+            show: false
+            required: false
+          invite_customer:
+            show: false
+            required: false
+      Organization:
+        Customer:
+          view:
+            shown: true
+        Agent:
+          create:
+            shown: true
+            required: false
+          edit:
+            shown: true
+            required: false
+          view:
+            shown: true
+        Admin:
+          create:
+            shown: true
+            required: false
+          edit:
+            shown: true
+            required: false
+          view:
+            shown: true
+      Group:
+        Admin:
+          create:
+            shown: true
+            required: false
+          edit:
+            shown: true
+            required: false
+          view:
+            shown: true
+    init = false
+    if params && !params.id
+      init = true
+    $(App.view('object_manager/screens')(
+      attribute: attribute
+      data: objects[object]
+      params: params
+      init: init
+    ))
+
+  @input: (item, localParams, params) ->
+    configureAttributes = [
+      { name: 'data_option::default', display: 'Default', tag: 'input', type: 'text', null: true, default: '' },
+    ]
+    inputDefault = new App.ControllerForm(
+      model:
+        configure_attributes: configureAttributes
+      noFieldset: true
+      params: params
+    )
+    configureAttributes = [
+      { name: 'data_option::type', display: 'Type', tag: 'select', null: false, default: 'text', options: {text: 'Text', phone: 'Phone', fax: 'Fax', email: 'Email', url: 'Url'}, translate: true },
+    ]
+    inputType = new App.ControllerForm(
+      model:
+        configure_attributes: configureAttributes
+      noFieldset: true
+      params: params
+    )
+    configureAttributes = [
+      { name: 'data_option::maxlength', display: 'Maxlength', tag: 'integer', null: false, default: 120 },
+    ]
+    inputMaxlength = new App.ControllerForm(
+      model:
+        configure_attributes: configureAttributes
+      noFieldset: true
+      params: params
+    )
+    item.find('.js-inputDefault').html(inputDefault.form)
+    item.find('.js-inputType').html(inputType.form)
+    item.find('.js-inputMaxlength').html(inputMaxlength.form)
+
+  @datetime: (item, localParams, params) ->
+    configureAttributes = [
+      { name: 'data_option::future', display: 'Allow future', tag: 'boolean', null: false, default: true },
+    ]
+    datetimeFuture = new App.ControllerForm(
+      model:
+        configure_attributes: configureAttributes
+      noFieldset: true
+      params: params
+    )
+    configureAttributes = [
+      { name: 'data_option::past', display: 'Allow past', tag: 'boolean', null: false, default: true },
+    ]
+    datetimePast = new App.ControllerForm(
+      model:
+        configure_attributes: configureAttributes
+      noFieldset: true
+      params: params
+    )
+    configureAttributes = [
+      { name: 'data_option::diff', display: 'Default time Diff (minutes)', tag: 'integer', null: false, default: 24 },
+    ]
+    datetimeDiff = new App.ControllerForm(
+      model:
+        configure_attributes: configureAttributes
+      noFieldset: true
+      params: params
+    )
+    item.find('.js-datetimeFuture').html(datetimeFuture.form)
+    item.find('.js-datetimePast').html(datetimePast.form)
+    item.find('.js-datetimeDiff').html(datetimeDiff.form)
+
+  @date: (item, localParams, params) ->
+    configureAttributes = [
+      { name: 'data_option::future', display: 'Allow future', tag: 'boolean', null: false, default: true },
+    ]
+    dateFuture = new App.ControllerForm(
+      model:
+        configure_attributes: configureAttributes
+      noFieldset: true
+      params: params
+    )
+    configureAttributes = [
+      { name: 'data_option::past', display: 'Allow past', tag: 'boolean', null: false, default: true },
+    ]
+    datePast = new App.ControllerForm(
+      model:
+        configure_attributes: configureAttributes
+      noFieldset: true
+      params: params
+    )
+    configureAttributes = [
+      { name: 'data_option::diff', display: 'Default time Diff (hours)', tag: 'integer', null: false, default: 24 },
+    ]
+    dateDiff = new App.ControllerForm(
+      model:
+        configure_attributes: configureAttributes
+      noFieldset: true
+      params: params
+    )
+    item.find('.js-dateFuture').html(dateFuture.form)
+    item.find('.js-datePast').html(datePast.form)
+    item.find('.js-dateDiff').html(dateDiff.form)
+
+  @integer: (item, localParams, params) ->
+    configureAttributes = [
+      { name: 'data_option::default', display: 'Default', tag: 'integer', null: true, default: '', min: 1 },
+    ]
+    integerDefault = new App.ControllerForm(
+      model:
+        configure_attributes: configureAttributes
+      noFieldset: true
+      params: params
+    )
+    configureAttributes = [
+      { name: 'data_option::min', display: 'Minimal', tag: 'integer', null: false, default: 0, min: 1 },
+    ]
+    integerMin = new App.ControllerForm(
+      model:
+        configure_attributes: configureAttributes
+      noFieldset: true
+      params: params
+    )
+    configureAttributes = [
+      { name: 'data_option::max', display: 'Maximal', tag: 'integer', null: false, default: 999999999, min: 2 },
+    ]
+    integerMax = new App.ControllerForm(
+      model:
+        configure_attributes: configureAttributes
+      noFieldset: true
+      params: params
+    )
+    item.find('.js-integerDefault').html(integerDefault.form)
+    item.find('.js-integerMin').html(integerMin.form)
+    item.find('.js-integerMax').html(integerMax.form)
+
+  @select: (item, localParams, params) ->
+
+  @boolean: (item, localParams, params) ->
+
+  @autocompletion: (item, localParams, params) ->
+    configureAttributes = [
+      { name: 'data_option::default', display: 'Default', tag: 'input', type: 'text', null: true, default: '' },
+    ]
+    autocompletionDefault = new App.ControllerForm(
+      model:
+        configure_attributes: configureAttributes
+      noFieldset: true
+      params: params
+    )
+    configureAttributes = [
+      { name: 'data_option::url', display: 'Url (AJAX Endpoint)', tag: 'input', type: 'url', null: false, default: '', placeholder: 'https://example.com/serials' },
+    ]
+    autocompletionUrl = new App.ControllerForm(
+      model:
+        configure_attributes: configureAttributes
+      noFieldset: true
+      params: params
+    )
+    configureAttributes = [
+      { name: 'data_option::method', display: 'Method (AJAX Endpoint)', tag: 'input', type: 'url', null: false, default: '', placeholder: 'GET' },
+    ]
+    autocompletionMethod = new App.ControllerForm(
+      model:
+        configure_attributes: configureAttributes
+      noFieldset: true
+      params: params
+    )
+
+    item.find('.js-autocompletionDefault').html(autocompletionDefault.form)
+    item.find('.js-autocompletionUrl').html(autocompletionUrl.form)
+    item.find('.js-autocompletionMethod').html(autocompletionMethod.form)

+ 125 - 0
app/assets/javascripts/app/controllers/_ui_element/user_permission.coffee

@@ -0,0 +1,125 @@
+# coffeelint: disable=camel_case_classes
+class App.UiElement.user_permission
+  @render: (attribute, params = {}) ->
+    attribute.options = {}
+
+    # get selectable roles and selected roles
+    roles = []
+    rolesSelected = {}
+    rolesRaw = App.Role.search(sortBy: 'name')
+    for role in rolesRaw
+      if role.active
+        roles.push role
+        if params.role_ids
+          for role_id in params.role_ids
+            if role_id.toString() is role.id.toString()
+              rolesSelected[role.id] = true
+
+    # get selectable groups and selected groups
+    groups = []
+    groupsSelected = {}
+    groupsRaw = App.Group.search(sortBy: 'name')
+    for group in groupsRaw
+      if group.active
+        groups.push group
+        if params.group_ids
+          for group_id in params.group_ids
+            if group_id.toString() is group.id.toString()
+              groupsSelected[group.id] = true
+
+    # if only one group is selectable, hide all groups
+    hideGroups = false
+    if groups.length <= 1
+      hideGroups = true
+
+    if attribute.hideMode
+      if attribute.hideMode.rolesSelected
+        roles = []
+        rolesSelected = {}
+        for roleName in attribute.hideMode.rolesSelected
+          role = App.Role.findByAttribute('name', roleName)
+          if role
+            roles.push role
+            rolesSelected[role.id] = true
+      if attribute.hideMode.rolesNot
+        for roleRaw in rolesRaw
+          hit = false
+          for roleName in attribute.hideMode.rolesNot
+            if roleRaw.active && roleRaw.name is roleName
+              hit = true
+          if !hit
+            roles.push roleRaw
+
+    # if agent is on new users selected, select all groups
+    if _.isEmpty(attribute.value)
+      agentRole = App.Role.findByAttribute('name', 'Agent')
+      if rolesSelected[agentRole.id]
+        for group in groups
+          groupsSelected[group.id] = true
+
+    # uniq and sort roles
+    roles = _.indexBy(roles, 'name')
+    roles = _.sortBy(roles, (i) -> return i.name)
+
+    item = $( App.view('generic/user_permission')(
+      attribute: attribute
+      roles: roles
+      groups: groups
+      params: params
+      rolesSelected: rolesSelected
+      groupsSelected: groupsSelected
+      hideGroups: hideGroups
+    ) )
+
+    getCurrentRoles = ->
+      currentRoles = []
+      item.find('[name=role_ids]').each( ->
+        element = $(@)
+        checked = element.prop('checked')
+        return if !checked
+        role_id = element.prop('value')
+        role = App.Role.find(role_id)
+        return if !role
+        currentRoles.push role
+      )
+      currentRoles
+
+    # if customer, remove admin and agent
+    item.find('[name=role_ids]').bind('change', (e) ->
+      element = $(e.currentTarget)
+      checked = element.prop('checked')
+      role_id = element.prop('value')
+      return if !role_id
+      role = App.Role.find(role_id)
+      return if !role
+
+      # if agent got deselected
+      # - hide groups
+      if !checked
+        if role.name is 'Agent'
+          item.find('.js-groupList').addClass('hidden')
+        return
+
+      # if agent is selected
+      # - show groups
+      if role.name is 'Agent'
+        item.find('.js-groupList:not(.js-groupListHide)').removeClass('hidden')
+
+      # if role customer is selected
+      # - deselect agent & admin
+      # - hide groups
+      if role.name is 'Customer'
+        for currentRole in getCurrentRoles()
+          if currentRole.name is 'Admin' || currentRole.name is 'Agent'
+            item.find("[name=role_ids][value=#{currentRole.id}]").prop('checked', false)
+        item.find('.js-groupList').addClass('hidden')
+
+      # if role agent or admin is selected
+      # - deselect customer
+      else if role.name is 'Agent' || role.name is 'Admin'
+        for currentRole in getCurrentRoles()
+          if currentRole.name is 'Customer'
+            item.find("[name=role_ids][value=#{currentRole.id}]").prop('checked', false)
+    )
+
+    item

+ 128 - 169
app/assets/javascripts/app/controllers/object_manager.coffee

@@ -14,7 +14,7 @@ class Index extends App.ControllerTabs
     @ajax(
       id:    'object_manager_attributes_list'
       type:  'GET'
-      url:   @apiPath + '/object_manager_attributes_list'
+      url:   "#{@apiPath}/object_manager_attributes_list"
       processData: true
       success: (data, status, xhr) =>
         @stopLoading()
@@ -36,22 +36,21 @@ class Index extends App.ControllerTabs
 
 class Items extends App.ControllerContent
   events:
-    'click [data-type="delete"]': 'destroy'
-    'click .js-up':               'move'
-    'click .js-down':             'move'
-    'click .js-new':              'new'
-    'click .js-edit':             'edit'
+    'click .js-delete':  'destroy'
+    'click .js-new':     'new'
+    'click .js-edit':    'edit'
+    'click .js-discard': 'discard'
+    'click .js-execute': 'execute'
 
   constructor: ->
     super
+
     # check authentication
     return if !@authenticate()
 
     @subscribeId = App.ObjectManagerAttribute.subscribe(@render)
     App.ObjectManagerAttribute.fetch()
 
-    # ajax call
-
   release: =>
     if @subscribeId
       App.ObjectManagerAttribute.unsubscribe(@subscribeId)
@@ -63,63 +62,22 @@ class Items extends App.ControllerContent
       sortBy: 'position'
     )
 
-    @html App.view('object_manager/index')(
-      head:  @object
-      items: items
-    )
-
-
-    ###
-    new App.ControllerTable(
-      el:         @el.find('.table-overview')
-      model:      App.ObjectManagerAttribute
-      objects:    objects
-      bindRow:
-        events:
-          'click': @edit
-    )
-    ###
-
-  move: (e) =>
-    e.preventDefault()
-    e.stopPropagation()
-    id        = $( e.target ).closest('tr').data('id')
-    direction = 'up'
-    if $( e.target ).hasClass('js-down')
-      direction = 'down'
-    console.log('M', id, direction)
+    itemsToChange = []
+    for item in App.ObjectManagerAttribute.search(sortBy: 'object')
+      if item.to_create is true || item.to_delete is true
+        itemsToChange.push item
 
-    items = App.ObjectManagerAttribute.search(
-      filter:
-        object: @object
-      sortBy: 'position'
+    @html App.view('object_manager/index')(
+      head:          @object
+      items:         items
+      itemsToChange: itemsToChange
     )
-    count = 0
-    for item in items
-      if item.id is id
-        if direction is 'up'
-          itemToMove = items[ count - 1 ]
-        else
-          itemToMove = items[ count + 1 ]
-        if itemToMove
-          movePosition = itemToMove.position
-          if movePosition is item.position
-            if direction is 'up'
-              movePosition -= 1
-            else
-              movePosition += 1
-          itemToMove.position = item.position
-          itemToMove.save()
-          console.log(itemToMove, itemToMove.position, count)
-          item.position = movePosition
-          item.save()
-          console.log(item, movePosition, count)
-      count += 1
 
   new: (e) =>
     e.preventDefault()
-    new App.ControllerGenericNew(
+    new New(
       pageData:
+        head:      @object
         title:     'Attribute'
         home:      'object_manager'
         object:    'ObjectManagerAttribute'
@@ -127,6 +85,8 @@ class Items extends App.ControllerContent
         navupdate: '#object_manager'
       genericObject: 'ObjectManagerAttribute'
       container:     @el.closest('.content')
+      item:
+        object: @object
     )
 
   edit: (e) =>
@@ -134,136 +94,135 @@ class Items extends App.ControllerContent
     id = $( e.target ).closest('tr').data('id')
     new Edit(
       pageData:
-        object: 'ObjectManagerAttribute'
+        head:      @object
+        title:     'Attribute'
+        home:      'object_manager'
+        object:    'ObjectManagerAttribute'
+        objects:   'ObjectManagerAttributes'
+        navupdate: '#object_manager'
       genericObject: 'ObjectManagerAttribute'
+      container:     @el.closest('.content')
       callback:      @render
       id:            id
-      container:     @el.closest('.content')
     )
 
   destroy: (e) ->
+    e.stopPropagation()
     e.preventDefault()
-    sessionId = $( e.target ).data('session-id')
+    id   = $(e.target).closest('tr').data('id')
+    item = App.ObjectManagerAttribute.find(id)
     @ajax(
-      id:    'sessions/' + sessionId
+      id:    "object_manager_attributes/#{id}"
       type:  'DELETE'
-      url:   @apiPath + '/sessions/' + sessionId
+      url:   "#{@apiPath}/object_manager_attributes/#{id}"
       success: (data) =>
-        @load()
+        @render()
     )
 
-class Edit extends App.ControllerModal
-  buttonClose: true
-  buttonCancel: true
-  buttonSubmit: true
-  head: 'Edit'
-
-  content: =>
-    content = $( App.view('object_manager/edit')(
-      head:  @object
-      items: []
-    ) )
-
-    item = App.ObjectManagerAttribute.find(@id)
-
-    options =
-      input:    'Text (normal - one line)'
-      select:   'Selection'
-      datetime: 'Datetime'
-      date:     'Date'
-      textarea: 'Text (normal - multiline)'
-      richtext: 'Text (richtext)'
-      checkbox: 'Checkbox'
-      boolean:  'yes/no'
-
-    configureAttributesTop = [
-      { name: 'name',       display: 'Name',    tag: 'input',     type: 'text', limit: 100, 'null': false },
-      { name: 'display',    display: 'Anzeige', tag: 'input',     type: 'text', limit: 100, 'null': false },
-      { name: 'data_type',  display: 'Format',  tag: 'select',    multiple: false, nulloption: true, null: false, options: options, translate: true },
-    ]
-    controller = new App.ControllerForm(
-      model:     { configure_attributes: configureAttributesTop, className: '' },
-      params:    item
-      #screen:   @screen || 'edit'
-      el:        content.find('.js-top')
-      autofocus: true
+  discard: (e) ->
+    e.preventDefault()
+    @ajax(
+      id:    'object_manager_attributes_discard_changes'
+      type:  'POST'
+      url:   "#{@apiPath}/object_manager_attributes_discard_changes"
+      success: (data) =>
+        @render()
     )
 
-    # input
-    configureAttributesInput = [
-      { name: 'data_option::type',            display: 'Type',            tag: 'select', multiple: false, nulloption: true, null: false, options: { text: 'text', email: 'email', url: 'url', email: 'email', password: 'password', phone: 'phone'}, translate: true },
-      { name: 'data_option::maxlength',       display: 'Max. Length',     tag: 'input',  type: 'text', limit: 100, 'null': false },
-      { name: 'data_option::null',            display: 'Required',        tag: 'select', multiple: false, nulloption: false, null: false, options: { true: 'no', false: 'yes' }, translate: true },
-      { name: 'data_option::autocapitalize',  display: 'autocapitalize',  tag: 'select', multiple: false, nulloption: true, null: false, options: { true: 'no', false: 'yes' }, translate: true },
-      { name: 'data_option::autocomplete',    display: 'autocomplete',    tag: 'select', multiple: false, nulloption: true, null: false, options: { true: 'no', false: 'yes' }, translate: true },
-      { name: 'data_option::default',         display: 'Default',         tag: 'input', type: 'text', limit: 100, null: true },
-      { name: 'data_option::note',            display: 'note',            tag: 'input', type: 'text', limit: 100, null: true },
-    ]
-    controller = new App.ControllerForm(
-      model:     { configure_attributes: configureAttributesInput, className: '' },
-      params:    item
-      el:        content.find('.js-input')
-      autofocus: true
+  execute: (e) ->
+    e.preventDefault()
+    @ajax(
+      id:    'object_manager_attributes_execute_migrations'
+      type:  'POST'
+      url:   "#{@apiPath}/object_manager_attributes_execute_migrations"
+      success: (data) =>
+        @render()
     )
 
-    # textarea
-    configureAttributesTextarea = [
-      { name: 'data_option::maxlength',       display: 'Max. Length',     tag: 'input',  type: 'text', limit: 100, null: false },
-      { name: 'data_option::null',            display: 'Required',        tag: 'select', multiple: false, nulloption: false, null: false, options: { true: 'no', false: 'yes' }, translate: true },
-      { name: 'data_option::autocapitalize',  display: 'autocapitalize',  tag: 'select', multiple: false, nulloption: true, null: false, options: { true: 'no', false: 'yes' }, translate: true },
-      { name: 'data_option::note',            display: 'autocomplete',    tag: 'input',  type: 'text', limit: 100, null: true },
-    ]
-    controller = new App.ControllerForm(
-      model:     { configure_attributes: configureAttributesTextarea, className: '' },
-      params:    item
-      el:        content.find('.js-textarea')
-      autofocus: true
+class New extends App.ControllerGenericNew
+
+  onSubmit: (e) =>
+    params = @formParam(e.target)
+    params.object = @pageData.head
+    object = new App[ @genericObject ]
+    object.load(params)
+
+    # validate
+    errors = object.validate()
+    if errors
+      @log 'error', errors
+      @formValidate( form: e.target, errors: errors )
+      return false
+
+    # disable form
+    @formDisable(e)
+
+    # save object
+    ui = @
+    object.save(
+      done: ->
+        if ui.callback
+          item = App[ ui.genericObject ].fullLocal(@id)
+          ui.callback(item)
+        ui.close()
+
+      fail: (settings, details) ->
+        ui.log 'errors', details
+        ui.formEnable(e)
+        ui.controller.showAlert(details.error_human || details.error || 'Unable to create object!')
     )
 
-    # select
-    configureAttributesSelect = [
-      { name: 'data_option::nulloption',      display: 'Empty Selection', tag: 'select', multiple: false, nulloption: false, null: false, options: { true: 'no', false: 'yes' }, translate: true },
-      { name: 'data_option::null',            display: 'Required',        tag: 'boolean', multiple: false, nulloption: false, null: false, options: { true: 'no', false: 'yes' }, translate: true },
-      { name: 'data_option::relation',        display: 'Relation',        tag: 'input',  type: 'text', limit: 100, null: true },
-      { name: 'data_option::options',         display: 'Options',         tag: 'hash',   multiple: true, null: false },
-      { name: 'data_option::translate',       display: 'Übersetzen',      tag: 'select', multiple: false, nulloption: false, null: false, options: { true: 'no', false: 'yes' }, translate: true },
-      { name: 'data_option::note',            display: 'Note',            tag: 'input',  type: 'text', limit: 100, null: true },
-    ]
-    controller = new App.ControllerForm(
-      model:      { configure_attributes: configureAttributesSelect, className: '' },
-      params:     item
-      el:         content.find('.js-select')
-      autofocus:  true
-    )
+class Edit extends App.ControllerGenericEdit
 
-    ###
-        :options => {
-          'Incident' => 'Incident',
-          'Problem'  => 'Problem',
-          'Request for Change' => 'Request for Change',
-        },
-    ###
-
-    content.find('[name=data_type]').on(
-      'change',
-      (e) ->
-        dataType = $( e.target ).val()
-        content.find('.js-middle > div').addClass('hide')
-        content.find(".js-#{dataType}").removeClass('hide')
+  content: =>
+    @item = App[ @genericObject ].find( @id )
+    @head = @pageData.head || @pageData.object
+
+    # set disabled attributes
+    configure_attributes = clone(App[ @genericObject ].configure_attributes)
+    for attribute in configure_attributes
+      if attribute.name is 'name'
+        attribute.disabled = true
+      #if attribute.name is 'data_type'
+      #  attribute.disabled = true
+
+    @controller = new App.ControllerForm(
+      model:
+        configure_attributes: configure_attributes
+      params:     @item
+      screen:     @screen || 'edit'
+      autofocus:  true
     )
-    content.find('[name=data_type]').trigger('change')
-
-
-    configureAttributesBottom = [
-      { name: 'active', display: 'Active', tag: 'active', default: true },
-    ]
-    controller = new App.ControllerForm(
-      model:   { configure_attributes: configureAttributesBottom, className: '' },
-      params:  item
-      #screen: @screen || 'edit'
-      el:      content.find('.js-bottom')
+    @controller.form
+
+  onSubmit: (e) =>
+    params = @formParam(e.target)
+    params.object = @pageData.head
+    @item.load(params)
+
+    # validate
+    errors = @item.validate()
+    if errors
+      @log 'error', errors
+      @formValidate( form: e.target, errors: errors )
+      return false
+
+    # disable form
+    @formDisable(e)
+
+    # save object
+    ui = @
+    @item.save(
+      done: ->
+        if ui.callback
+          item = App[ ui.genericObject ].fullLocal(@id)
+          ui.callback(item)
+        ui.close()
+
+      fail: (settings, details) ->
+        ui.log 'errors'
+        ui.formEnable(e)
+        ui.controller.showAlert(details.error_human || details.error || 'Unable to update object!')
     )
 
-    controller.form
-
 App.Config.set( 'SystemObject', { prio: 1700, parent: '#system', name: 'Objects', target: '#system/object_manager', controller: Index, role: ['Admin'] }, 'NavBarAdmin' )

+ 7 - 7
app/assets/javascripts/app/controllers/widget/invite_user.coffee

@@ -43,16 +43,16 @@ class App.InviteUser extends App.WizardModal
     e.preventDefault()
     @showSlide('js-waiting')
     @formDisable(e)
-    @params          = @formParam(e.target)
-    @params.role_ids = [0]
+    @params = @formParam(e.target)
 
     # set invite flag
     @params.invite = true
 
     # find agent role
-    role = App.Role.findByAttribute('name', @role)
-    if role
-      @params.role_ids = role.id
+    if @role
+      role = App.Role.findByAttribute('name', @role)
+      if role
+        @params.role_ids = role.id
 
     user = new App.User
     user.load(@params)
@@ -62,7 +62,7 @@ class App.InviteUser extends App.WizardModal
     )
     if errors
       @log 'error new', errors
-      @formValidate( form: e.target, errors: errors )
+      @formValidate(form: e.target, errors: errors)
       @formEnable(e)
       @showSlide('js-user')
       return false
@@ -77,4 +77,4 @@ class App.InviteUser extends App.WizardModal
         @formEnable(e)
         @showSlide('js-user')
         @showAlert('js-user',  details.error_human || details.error)
-    )
+    )

+ 12 - 12
app/assets/javascripts/app/models/_application_model.coffee

@@ -597,33 +597,33 @@ class App.Model extends Spine.Model
     all_complied = []
     if !params
       for item in all
-        item_new = @find( item.id )
+        item_new = @find(item.id)
         all_complied.push @_fillUp(item_new)
       return all_complied
     for item in all
-      item_new = @find( item.id )
+      item_new = @find(item.id)
       all_complied.push @_fillUp(item_new)
 
     # filter search
     if params.filter
-      all_complied = @_filter( all_complied, params.filter )
+      all_complied = @_filter(all_complied, params.filter)
 
     # use extend filter search
     if params.filterExtended
-      all_complied = @_filterExtended( all_complied, params.filterExtended )
+      all_complied = @_filterExtended(all_complied, params.filterExtended)
 
     # sort by
     if params.sortBy != null
-      all_complied = @_sortBy( all_complied, params.sortBy )
+      all_complied = @_sortBy(all_complied, params.sortBy)
 
     # order
     if params.order
-      all_complied = @_order( all_complied, params.order )
+      all_complied = @_order(all_complied, params.order)
 
     all_complied
 
-  @_sortBy: ( collection, attribute ) ->
-    _.sortBy( collection, (item) ->
+  @_sortBy: (collection, attribute) ->
+    _.sortBy(collection, (item) ->
 
       # set displayName as default sort attribute
       if !attribute
@@ -646,20 +646,20 @@ class App.Model extends Spine.Model
       item[ attribute ]
     )
 
-  @_order: ( collection, attribute ) ->
+  @_order: (collection, attribute) ->
     if attribute is 'DESC'
       return collection.reverse()
     collection
 
-  @_filter: ( collection, filter ) ->
+  @_filter: (collection, filter) ->
     for key, value of filter
-      collection = _.filter( collection, (item) ->
+      collection = _.filter(collection, (item) ->
         if item[key] is value
           return item
       )
     collection
 
-  @_filterExtended: ( collection, filters ) ->
+  @_filterExtended: (collection, filters) ->
     collection = _.filter( collection, (item) ->
 
       # check all filters

+ 2 - 2
app/assets/javascripts/app/models/group.coffee

@@ -6,8 +6,8 @@ class App.Group extends App.Model
   @configure_attributes = [
     { name: 'name',                 display: 'Name',              tag: 'input',  type: 'text', limit: 100, null: false },
     { name: 'assignment_timeout',   display: 'Assignment Timeout', tag: 'input', note: 'Assignment timeout in minutes if assigned agent is not working on it. Ticket will be shown as unassigend.', type: 'text', limit: 100, null: true },
-    { name: 'follow_up_possible',   display: 'Follow up possible',tag: 'select', default: 'yes', options: { yes: 'yes', reject: 'reject follow up/do not reopen Ticket', 'new_ticket': 'do not reopen Ticket but create new Ticket' }, null: false, note: 'Follow up for closed ticket possible or not.' },
-    { name: 'follow_up_assignment', display: 'Assign Follow Ups', tag: 'select', default: 'yes', options: { true: 'yes', false: 'no' }, 'null': false, note: 'Assign follow up to latest agent again.' },
+    { name: 'follow_up_possible',   display: 'Follow up possible',tag: 'select', default: 'yes', options: { yes: 'yes', reject: 'reject follow up/do not reopen Ticket', 'new_ticket': 'do not reopen Ticket but create new Ticket' }, null: false, note: 'Follow up for closed ticket possible or not.', translate: true },
+    { name: 'follow_up_assignment', display: 'Assign Follow Ups', tag: 'select', default: 'yes', options: { true: 'yes', false: 'no' }, null: false, note: 'Assign follow up to latest agent again.', translate: true },
     { name: 'email_address_id',     display: 'Email',             tag: 'select', multiple: false, null: true, relation: 'EmailAddress', nulloption: true, do_not_log: true },
     { name: 'signature_id',         display: 'Signature',         tag: 'select', multiple: false, null: true, relation: 'Signature', nulloption: true, do_not_log: true },
     { name: 'note',                 display: 'Note',              tag: 'textarea', note: 'Notes are visible to agents only, never to customers.', limit: 250, null: true },

Some files were not shown because too many files changed in this diff