diff --git a/app/assets/javascripts/app/controllers/_application_controller_table.coffee b/app/assets/javascripts/app/controllers/_application_controller_table.coffee index 27395ec26..28b7ec3fe 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_table.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_table.coffee @@ -98,6 +98,7 @@ class App.ControllerTable extends App.Controller radioColWidth: 22 sortableColWidth: 36 destroyColWidth: 70 + cloneColWidth: 70 elements: '.js-tableHead': 'tableHead' @@ -148,6 +149,7 @@ class App.ControllerTable extends App.Controller @attributesListRaw ||= @attribute_list || @model.configure_attributes || {} @attributesList = App.Model.attributesGet(false, @attributesListRaw) @destroy = @model.configure_delete + @clone = @model.configure_clone throw 'overviewAttributes needed' if _.isEmpty(@overviewAttributes) throw 'attributesList needed' if _.isEmpty(@attributesList) @@ -343,7 +345,7 @@ class App.ControllerTable extends App.Controller (e) -> e.stopPropagation() id = $(e.target).parents('tr').data('id') - callback(id, e) + callback(id, e, e.currentTarget) ) # bind row @@ -494,6 +496,7 @@ class App.ControllerTable extends App.Controller sortable: @dndCallback position: position object: object + actions: @actions ) tableHeadersHasChanged: => @@ -511,6 +514,7 @@ class App.ControllerTable extends App.Controller # get header data @headers = [] + @actions = [] availableWidth = @availableWidth for item in @overviewAttributes headerFound = false @@ -564,25 +568,54 @@ class App.ControllerTable extends App.Controller for callback in @callbackHeader @headers = callback(@headers) - if @tableId - @calculateHeaderWidths() - throw 'no headers found' if _.isEmpty(@headers) - # add destroy header and col binding - if @destroy - @headers.push - name: 'destroy' - display: 'Delete' - width: '70px' - displayWidth: 70 - unresizable: true - parentClass: 'js-delete' - icon: 'trash' + if @clone + @actions.push + name: 'clone' + display: 'Clone' + icon: 'clipboard' + class: 'create js-clone' + callback: (id) => + item = @model.find(id) + item.name = "Clone: #{item.name}" + new App.ControllerGenericNew + item: item + pageData: + object: item.constructor.name + callback: => + @renderTableFull() + genericObject: item.constructor.name + container: @container - @bindCol['destroy'] = + if @destroy + @actions.push + name: 'delete' + display: 'Delete' + icon: 'trash' + class: 'danger js-delete' + callback: (id) => + item = @model.find(id) + new App.ControllerGenericDestroyConfirm + item: item + container: @container + + if @actions.length + @headers.push + name: 'action' + display: 'Action' + width: '38px' + displayWidth: 38 + unresizeable: true + align: 'right' + parentClass: 'noTruncate no-padding' + + @bindCol['action'] = events: - click: @deleteRow + click: @toggleActionDropdown + + if @tableId + @calculateHeaderWidths() @columnsLength = @headers.length if @checkbox || @radio @@ -732,14 +765,30 @@ class App.ControllerTable extends App.Controller @objects = localObjects @lastSortedobjects = localObjects - # bind on delete dialog - deleteRow: (id, e) => + onActionButtonClicked: (e) => + id = $(e.currentTarget).parents('tr').data('id') + name = e.currentTarget.getAttribute('data-table-action') + @runAction(name, id) + console.log 'onActionButtonClicked' + + runAction: (name, id) => + action = _.findWhere @actions, name: name + action.callback(id) + + toggleActionDropdown: (id, e, td) => e.stopPropagation() - e.preventDefault() - item = @model.find(id) - new App.ControllerGenericDestroyConfirm - item: item - container: @container + $dropdown = $(td).find('.js-table-action-menu') + if $dropdown.length + # open dropdown + $dropdown.dropdown('toggle') + # bind on click now that the dropdown is open + $dropdown.one('click.dropdown', '[data-table-action]', @onActionButtonClicked) + # unbind after dropdown is closed + $dropdown.parent().one('hide.bs.dropdown', -> $dropdown.off('click.dropdown')) + else + # only one action - directly fire that action + name = $(td).find('[data-table-action]').attr('data-table-action') + @runAction(name, id) calculateHeaderWidths: -> return if !@headers @@ -789,6 +838,9 @@ class App.ControllerTable extends App.Controller if @destroy widths += @destroyColWidth + if @clone + widths += @cloneColWidth + widths setHeaderWidths: => diff --git a/app/assets/javascripts/app/models/group.coffee b/app/assets/javascripts/app/models/group.coffee index 2812b0b92..e0720453c 100644 --- a/app/assets/javascripts/app/models/group.coffee +++ b/app/assets/javascripts/app/models/group.coffee @@ -14,6 +14,7 @@ class App.Group extends App.Model { name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 }, { name: 'active', display: 'Active', tag: 'active', default: true }, ] + @configure_clone = true @configure_overview = [ 'name', ] diff --git a/app/assets/javascripts/app/models/job.coffee b/app/assets/javascripts/app/models/job.coffee index d061c2db0..6107a1073 100644 --- a/app/assets/javascripts/app/models/job.coffee +++ b/app/assets/javascripts/app/models/job.coffee @@ -21,6 +21,7 @@ class App.Job extends App.Model { name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 }, ] @configure_delete = true + @configure_clone = true @configure_overview = [ 'name', 'last_run_at', diff --git a/app/assets/javascripts/app/models/macro.coffee b/app/assets/javascripts/app/models/macro.coffee index 593e1df6d..a755a2ca1 100644 --- a/app/assets/javascripts/app/models/macro.coffee +++ b/app/assets/javascripts/app/models/macro.coffee @@ -10,6 +10,7 @@ class App.Macro extends App.Model { name: 'active', display: 'Active', tag: 'active', default: true }, ] @configure_delete = true + @configure_clone = true @configure_overview = [ 'name', ] diff --git a/app/assets/javascripts/app/models/organization.coffee b/app/assets/javascripts/app/models/organization.coffee index 7ce873f2d..240d9cc3c 100644 --- a/app/assets/javascripts/app/models/organization.coffee +++ b/app/assets/javascripts/app/models/organization.coffee @@ -10,6 +10,7 @@ class App.Organization extends App.Model { name: 'updated_by_id', display: 'Updated by', relation: 'User', readonly: 1, info: false }, { name: 'updated_at', display: 'Updated at', tag: 'datetime', readonly: 1, info: false }, ] + @configure_clone = true @configure_overview = [ 'name', 'shared', diff --git a/app/assets/javascripts/app/models/overview.coffee b/app/assets/javascripts/app/models/overview.coffee index b9b61bc2c..c02aed060 100644 --- a/app/assets/javascripts/app/models/overview.coffee +++ b/app/assets/javascripts/app/models/overview.coffee @@ -60,6 +60,7 @@ class App.Overview extends App.Model { name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 }, ] @configure_delete = true + @configure_clone = true @configure_overview = [ 'name', 'link', diff --git a/app/assets/javascripts/app/models/report_profile.js.coffee b/app/assets/javascripts/app/models/report_profile.js.coffee index a21fa0458..a7546bcfd 100644 --- a/app/assets/javascripts/app/models/report_profile.js.coffee +++ b/app/assets/javascripts/app/models/report_profile.js.coffee @@ -9,6 +9,7 @@ class App.ReportProfile extends App.Model { name: 'active', display: 'Active', tag: 'active', default: true }, ] @configure_delete = true + @configure_clone = true @configure_overview = [ 'name', ] diff --git a/app/assets/javascripts/app/models/role.coffee b/app/assets/javascripts/app/models/role.coffee index 994f64199..13202c324 100644 --- a/app/assets/javascripts/app/models/role.coffee +++ b/app/assets/javascripts/app/models/role.coffee @@ -13,6 +13,7 @@ class App.Role extends App.Model { name: 'updated_by_id', display: 'Updated by', relation: 'User', readonly: 1 }, { name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 }, ] + @configure_clone = true @configure_overview = [ 'name', 'default_at_signup', ] diff --git a/app/assets/javascripts/app/models/text_module.coffee b/app/assets/javascripts/app/models/text_module.coffee index 13d02d40f..e09958de0 100644 --- a/app/assets/javascripts/app/models/text_module.coffee +++ b/app/assets/javascripts/app/models/text_module.coffee @@ -27,6 +27,7 @@ class App.TextModule extends App.Model { name: 'active', display: 'Active', tag: 'active', default: true }, ] @configure_delete = true + @configure_clone = true @configure_overview = [ 'name', 'keywords', diff --git a/app/assets/javascripts/app/models/trigger.coffee b/app/assets/javascripts/app/models/trigger.coffee index 093feea5a..ca732eaf2 100644 --- a/app/assets/javascripts/app/models/trigger.coffee +++ b/app/assets/javascripts/app/models/trigger.coffee @@ -10,6 +10,7 @@ class App.Trigger extends App.Model { name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 }, ] @configure_delete = true + @configure_clone = true @configure_overview = [ 'name', ] diff --git a/app/assets/javascripts/app/views/generic/table_row.jst.eco b/app/assets/javascripts/app/views/generic/table_row.jst.eco index c414bca04..61689925d 100644 --- a/app/assets/javascripts/app/views/generic/table_row.jst.eco +++ b/app/assets/javascripts/app/views/generic/table_row.jst.eco @@ -36,6 +36,29 @@ <%- @Icon('task-state', header.class) %> <% else if header.icon: %> <%- @Icon(header.icon) %> + <% else if header.name is 'action': %> + <% if @actions.length > 1: %> + + <% else: %> +
+ <%- @Icon(@actions[0].icon) %> +
+ <% end %> <% else: %> <% if header.link: %> target="<%= header.target %>"<% end %>> diff --git a/app/assets/stylesheets/svg-dimensions.css b/app/assets/stylesheets/svg-dimensions.css index df97c6d2b..c1257a214 100644 --- a/app/assets/stylesheets/svg-dimensions.css +++ b/app/assets/stylesheets/svg-dimensions.css @@ -68,6 +68,7 @@ .icon-one-ticket { width: 48px; height: 10px; } .icon-organization { width: 16px; height: 16px; } .icon-outbound-calls { width: 17px; height: 17px; } +.icon-overflow-button { width: 3px; height: 13px; } .icon-overviews { width: 24px; height: 24px; } .icon-package { width: 16px; height: 16px; } .icon-paperclip { width: 28px; height: 28px; } diff --git a/app/assets/stylesheets/zammad.scss b/app/assets/stylesheets/zammad.scss index 54b9f4117..cfa3e939f 100644 --- a/app/assets/stylesheets/zammad.scss +++ b/app/assets/stylesheets/zammad.scss @@ -426,6 +426,19 @@ pre code.hljs { .icon { vertical-align: middle; @include bidi-style(margin-right, 5px, margin-left, 0); + + &:only-child { + @include bidi-style(margin-right, 5px, margin-left, 0); + } + } + + .btn-label { + margin-left: 0; + } + + &.btn--text { + padding: 4px 9px; + margin: 5px 6px 0; } } @@ -463,6 +476,10 @@ pre code.hljs { &.btn--slim { padding-left: 7px !important; padding-right: 7px !important; + + .btn-label { + @include bidi-style(margin-left, 0, margin-right, 0); + } &.btn--small { padding-left: 5px !important; @@ -1050,9 +1067,12 @@ th.align-right { } } -.table .icon-draggable, -.table .icon-trash { +.table .icon { vertical-align: middle; + fill: currentColor; +} + +.table .icon-draggable { fill: hsl(240,1%,77%); } @@ -6490,6 +6510,16 @@ footer { box-shadow: none; } + .dropdown-menu > li.danger:hover, + .dropdown-menu > li.danger.is-active { + background: hsl(0,65%,55%); + } + + .dropdown-menu > li.create:hover, + .dropdown-menu > li.create.is-active { + background: hsl(145,51%,45%); + } + .dropdown-menu > li > a { color: inherit; padding: 0 15px; @@ -6499,7 +6529,7 @@ footer { .dropdown-menu > li > a:hover { color: inherit; - background: hsl(205,90%,60%); + background: none; } .dropdown-menu > li > a span { diff --git a/contrib/icon-sprite.sketch b/contrib/icon-sprite.sketch index 0e377212c..6d28ea285 100644 Binary files a/contrib/icon-sprite.sketch and b/contrib/icon-sprite.sketch differ diff --git a/public/assets/images/icons.svg b/public/assets/images/icons.svg index 987a49cb2..486c615d2 100644 --- a/public/assets/images/icons.svg +++ b/public/assets/images/icons.svg @@ -467,6 +467,11 @@ + + + overflow-button + + overviews diff --git a/public/assets/images/icons/overflow-button.svg b/public/assets/images/icons/overflow-button.svg new file mode 100644 index 000000000..3919ad7c3 --- /dev/null +++ b/public/assets/images/icons/overflow-button.svg @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="3px" height="13px" viewBox="0 0 3 13" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch --> + <title>overflow-button + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/public/assets/tests/table.js b/public/assets/tests/table.js index afc73b58c..8754aaa8d 100644 --- a/public/assets/tests/table.js +++ b/public/assets/tests/table.js @@ -357,11 +357,11 @@ test('table test', function() { equal(el.find('tbody > tr:nth-child(5) > td:nth-child(1) input').val(), '1', 'check row 5') }); -test('table test 2', function() { +test('table test 2.1', function() { App.i18n.set('de-de') - $('#table').append('

table with hash

') - var el = $('#table-hash1') + $('#table').append('

table with hash

') + var el = $('#table-hash2_1') App.Group.refresh( [ { id: 5, @@ -372,6 +372,7 @@ test('table test 2', function() { ]) App.Channel.configure_delete = true + App.Channel.configure_clone = false App.Channel.configure_attributes = [ { name: 'adapter', display: 'Type', tag: 'select', multiple: false, null: false, options: { IMAP: 'IMAP', POP3: 'POP3' } }, { name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false }, @@ -418,24 +419,192 @@ test('table test 2', function() { equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Host', 'check header') equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Benutzer', 'check header') equal(el.find('table > thead > tr > th:nth-child(4)').text().trim(), 'Aktiv', 'check header') - equal(el.find('table > thead > tr > th:nth-child(5)').text().trim(), 'Löschen', 'check header') + equal(el.find('table > thead > tr > th:nth-child(5)').text().trim(), 'Aktion', 'check header') equal(el.find('tbody > tr:nth-child(1) > td').length, 5, 'check row 1') equal(el.find('tbody > tr:nth-child(1) > td:nth-child(1)').text().trim(), 'adapter1', 'check row 1') equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), 'host1', 'check row 1') equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'user1', 'check row 1') equal(el.find('tbody > tr:nth-child(1) > td:nth-child(4)').text().trim(), 'ja', 'check row 1') equal(el.find('tbody > tr:nth-child(1) > td:nth-child(5)').text().trim(), '', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(5) .dropdown.dropdown--actions').length, 0, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(5) .js-delete').length, 1, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(5) .js-clone').length, 0, 'check row 1') equal(el.find('tbody > tr:nth-child(2) > td').length, 5, 'check row 2') equal(el.find('tbody > tr:nth-child(2) > td:nth-child(1)').text().trim(), 'adapter2', 'check row 2') equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), 'host2', 'check row 2') equal(el.find('tbody > tr:nth-child(2) > td:nth-child(3)').text().trim(), 'user2', 'check row 2') equal(el.find('tbody > tr:nth-child(2) > td:nth-child(4)').text().trim(), 'ja', 'check row 2') equal(el.find('tbody > tr:nth-child(2) > td:nth-child(5)').text().trim(), '', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(5) .dropdown.dropdown--actions').length, 0, 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(5) .js-delete').length, 1, 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(5) .js-clone').length, 0, 'check row 1') +}); + +test('table test 2.2', function() { + App.i18n.set('de-de') + + $('#table').append('

table with hash

') + var el = $('#table-hash2_2') + App.Group.refresh( [ + { + id: 5, + name: 'group 5', + active: true, + created_at: '2014-06-10T11:17:34.000Z', + }, + ]) + + App.Channel.configure_delete = false + App.Channel.configure_clone = true + App.Channel.configure_attributes = [ + { name: 'adapter', display: 'Type', tag: 'select', multiple: false, null: false, options: { IMAP: 'IMAP', POP3: 'POP3' } }, + { name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false }, + { name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false }, + { name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false }, + { name: 'options::ssl', display: 'SSL', tag: 'select', multiple: false, null: true, options: { true: 'yes', false: 'no' }, translate: true, default: true}, + { name: 'options::folder', display: 'Folder', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false }, + { name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: false, nulloption: true, relation: 'Group' }, + { name: 'active', display: 'Active', tag: 'select', multiple: false, null: false, options: { true: 'yes', false: 'no' }, translate: true, default: true }, + ] + + App.Channel.refresh( [ + { + id: 1, + adapter: 'adapter1', + options: { + host: 'host1', + user: 'user1', + }, + group_id: 5, + active: true, + created_at: '2014-06-10T11:17:34.000Z', + }, + { + id: 2, + adapter: 'adapter2', + options: { + host: 'host2', + user: 'user2', + }, + group_id: 5, + active: true, + created_at: '2014-06-10T11:17:34.000Z', + }, + ] ) + new App.ControllerTable({ + el: el, + overview: ['adapter', 'options::host', 'options::user', 'active'], + model: App.Channel, + objects: App.Channel.search({sortBy:'adapter', order: 'ASC'}), + }) + equal(el.find('table > thead > tr').length, 1, 'row count') + equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Typ', 'check header') + equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Host', 'check header') + equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Benutzer', 'check header') + equal(el.find('table > thead > tr > th:nth-child(4)').text().trim(), 'Aktiv', 'check header') + equal(el.find('table > thead > tr > th:nth-child(5)').text().trim(), 'Aktion', 'check header') + equal(el.find('tbody > tr:nth-child(1) > td').length, 5, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(1)').text().trim(), 'adapter1', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), 'host1', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'user1', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(4)').text().trim(), 'ja', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(5)').text().trim(), '', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(5) .dropdown.dropdown--actions').length, 0, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(5) .js-delete').length, 0, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(5) .js-clone').length, 1, 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td').length, 5, 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(1)').text().trim(), 'adapter2', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), 'host2', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(3)').text().trim(), 'user2', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(4)').text().trim(), 'ja', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(5)').text().trim(), '', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(5) .dropdown.dropdown--actions').length, 0, 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(5) .js-delete').length, 0, 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(5) .js-clone').length, 1, 'check row 1') }); test('table test 3', function() { App.i18n.set('de-de') + $('#table').append('

table with hash

') + var el = $('#table-hash2') + App.Group.refresh( [ + { + id: 5, + name: 'group 5', + active: true, + created_at: '2014-06-10T11:17:34.000Z', + }, + ]) + + App.Channel.configure_delete = true + App.Channel.configure_clone = true + App.Channel.configure_attributes = [ + { name: 'adapter', display: 'Type', tag: 'select', multiple: false, null: false, options: { IMAP: 'IMAP', POP3: 'POP3' } }, + { name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false }, + { name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false }, + { name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false }, + { name: 'options::ssl', display: 'SSL', tag: 'select', multiple: false, null: true, options: { true: 'yes', false: 'no' }, translate: true, default: true}, + { name: 'options::folder', display: 'Folder', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false }, + { name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: false, nulloption: true, relation: 'Group' }, + { name: 'active', display: 'Active', tag: 'select', multiple: false, null: false, options: { true: 'yes', false: 'no' }, translate: true, default: true }, + ] + + App.Channel.refresh( [ + { + id: 1, + adapter: 'adapter1', + options: { + host: 'host1', + user: 'user1', + }, + group_id: 5, + active: true, + created_at: '2014-06-10T11:17:34.000Z', + }, + { + id: 2, + adapter: 'adapter2', + options: { + host: 'host2', + user: 'user2', + }, + group_id: 5, + active: true, + created_at: '2014-06-10T11:17:34.000Z', + }, + ] ) + new App.ControllerTable({ + el: el, + overview: ['adapter', 'options::host', 'options::user', 'active'], + model: App.Channel, + objects: App.Channel.search({sortBy:'adapter', order: 'ASC'}), + }) + equal(el.find('table > thead > tr').length, 1, 'row count') + equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Typ', 'check header') + equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Host', 'check header') + equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Benutzer', 'check header') + equal(el.find('table > thead > tr > th:nth-child(4)').text().trim(), 'Aktiv', 'check header') + equal(el.find('table > thead > tr > th:nth-child(5)').text().trim(), 'Aktion', 'check header') + equal(el.find('tbody > tr:nth-child(1) > td').length, 5, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(1)').text().trim(), 'adapter1', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), 'host1', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'user1', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(4)').text().trim(), 'ja', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(5) .dropdown.dropdown--actions .js-delete').length, 1, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(5) .dropdown.dropdown--actions .js-clone').length, 1, 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td').length, 5, 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(1)').text().trim(), 'adapter2', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), 'host2', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(3)').text().trim(), 'user2', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(4)').text().trim(), 'ja', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(5) .dropdown.dropdown--actions .js-delete').length, 1, 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(5) .dropdown.dropdown--actions .js-clone').length, 1, 'check row 2') +}); + +test('table test 4', function() { + App.i18n.set('de-de') + $('#table').append('

table with link

') var el = $('#table-link1') App.EmailAddress.refresh( [ @@ -532,7 +701,7 @@ test('table test 3', function() { }); -test('table test 4', function() { +test('table test 5', function() { App.i18n.set('de-de') $('#table').append('

table with data

')