Implemented issue #1133 - Added generic clone method for admin features.

This commit is contained in:
Martin Edenhofer 2018-03-06 11:44:38 +01:00
parent 0d644ea7c7
commit 95e5eb57a8
17 changed files with 332 additions and 31 deletions

View file

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

View file

@ -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',
]

View file

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

View file

@ -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',
]

View file

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

View file

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

View file

@ -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',
]

View file

@ -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',
]

View file

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

View file

@ -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',
]

View file

@ -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: %>
<div class="dropdown dropdown--actions">
<div class="btn btn--table btn--text btn--secondary js-action" id="tableActions" data-toggle="dropdown">
<%- @Icon('overflow-button') %>
</div>
<ul class="dropdown-menu dropdown-menu-right js-table-action-menu" role="menu" aria-labelledby="tableActions">
<% for action in @actions: %>
<li role="presentation" class="<%= action.class %>" data-table-action="<%= action.name %>">
<a role="menuitem" tabindex="-1">
<span class="dropdown-iconSpacer">
<%- @Icon(action.icon) %>
</span>
<%- @T(action.display) %>
</a>
<% end %>
</ul>
</div>
<% else: %>
<div class="btn btn--table btn--text btn--secondary <%= @actions[0].class %>" title="<%= @actions[0].display %>" data-table-action="<%= @actions[0].name %>">
<%- @Icon(@actions[0].icon) %>
</div>
<% end %>
<% else: %>
<% if header.link: %>
<a href="<%- header.link %>" <% if header.target: %>target="<%= header.target %>"<% end %>>

View file

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

View file

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

Binary file not shown.

View file

@ -467,6 +467,11 @@
<path d="M10.244 10l3.024-3.122 2.05 2.05L16 2l-6.927.683 2.05 2.05L8 7.852"/>
<path d="M2.05 1.598c.64-.642 2.574-.748 2.59-.41.014.34 1.742 4.105 1.758 4.444.014.34-1.14 1.496-1.478 1.835-.335.336 2.258 3.273 2.307 3.328.056.05 2.987 2.65 3.32 2.314.34-.34 1.493-1.497 1.832-1.482.337.015 4.093 1.747 4.432 1.762.338.016.232 1.954-.41 2.597-.546.548-3.38 2.54-8.31-1.017-.542-.312-1.398-1.027-2.696-2.327-.002 0-.002-.002-.002-.002l-.004-.002-.002-.003-.004-.003c-1.297-1.3-2.01-2.16-2.32-2.7C-.487 4.988 1.5 2.146 2.048 1.597z"/>
</g>
</symbol><symbol id="icon-overflow-button" viewBox="0 0 3 13">
<title>
overflow-button
</title>
<path d="M1.5 3C.672 3 0 2.328 0 1.5S.672 0 1.5 0 3 .672 3 1.5 2.328 3 1.5 3zm0 5C.672 8 0 7.328 0 6.5S.672 5 1.5 5 3 5.672 3 6.5 2.328 8 1.5 8zm0 5C.672 13 0 12.328 0 11.5S.672 10 1.5 10s1.5.672 1.5 1.5S2.328 13 1.5 13z" fill-rule="evenodd"/>
</symbol><symbol id="icon-overviews" viewBox="0 0 24 24">
<title>
overviews

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 73 KiB

View file

@ -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</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="overflow-button" fill="#50E3C2">
<path d="M1.5,3 C0.671572875,3 0,2.32842712 0,1.5 C0,0.671572875 0.671572875,0 1.5,0 C2.32842712,0 3,0.671572875 3,1.5 C3,2.32842712 2.32842712,3 1.5,3 Z M1.5,8 C0.671572875,8 0,7.32842712 0,6.5 C0,5.67157288 0.671572875,5 1.5,5 C2.32842712,5 3,5.67157288 3,6.5 C3,7.32842712 2.32842712,8 1.5,8 Z M1.5,13 C0.671572875,13 0,12.3284271 0,11.5 C0,10.6715729 0.671572875,10 1.5,10 C2.32842712,10 3,10.6715729 3,11.5 C3,12.3284271 2.32842712,13 1.5,13 Z" id="overflow"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 999 B

View file

@ -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('<hr><h1>table with hash</h1><div id="table-hash1"></div>')
var el = $('#table-hash1')
$('#table').append('<hr><h1>table with hash</h1><div id="table-hash2_1"></div>')
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('<hr><h1>table with hash</h1><div id="table-hash2_2"></div>')
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('<hr><h1>table with hash</h1><div id="table-hash2"></div>')
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('<hr><h1>table with link</h1><div id="table-link1"></div>')
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('<hr><h1>table with data</h1><div id="table-data1"></div>')