Stilted table generation into separate eco files. Improved mem usage.

This commit is contained in:
Martin Edenhofer 2017-03-18 22:13:04 +01:00
parent d2070f4407
commit 21d575dbfd
12 changed files with 197 additions and 221 deletions

View file

@ -88,8 +88,8 @@ class App.ControllerTable extends App.Controller
console.log('new header is', headers)
headers
callbackAttributes = (value, object, attribute, header, refObject) ->
console.log('data of item col', value, object, attribute, header, refObject)
callbackAttributes = (value, object, attribute, header) ->
console.log('data of item col', value, object, attribute, header)
value = 'New Data To Show'
value
@ -288,19 +288,44 @@ class App.ControllerTable extends App.Controller
if @tableId
@calculateHeaderWidths()
# get content
# generate content
position = 0
columnsLength = @headers.length
if @checkbox || @radio
columnsLength++
groupLast = ''
tableBody = ''
for object in @objects
if @groupBy
groupByName = App.viewPrint(object, @groupBy, attributes)
if groupLast isnt groupByName
groupLast = groupByName
tableBody += App.view('generic/table_row_group_by')(
position: position
groupByName: groupByName
columnsLength: columnsLength
)
position++
tableBody += App.view('generic/table_row')(
headers: @headers
attributes: attributes
checkbox: @checkbox
radio: @radio
callbacks: @callbackAttributes
sortable: @dndCallback
position: position
object: object
)
# generate full table
table = App.view('generic/table')(
tableId: @tableId
header: @headers
attributes: attributes
objects: @objects
headers: @headers
checkbox: @checkbox
radio: @radio
groupBy: @groupBy
class: @class
destroy: destroy
callbacks: @callbackAttributes
sortable: @dndCallback
tableBody: tableBody
)
# convert to jquery object

View file

@ -46,11 +46,11 @@ class Index extends App.ControllerSubContent
headers.splice(4, 0, attribute)
headers
callbackViewAttributes = (value, object, attribute, header, refObject) ->
callbackViewAttributes = (value, object, attribute, header) ->
value = 'X'
value
callbackTokenAttributes = (value, object, attribute, header, refObject) ->
callbackTokenAttributes = (value, object, attribute, header) ->
value = 'X'
value

View file

@ -608,48 +608,6 @@ class App.TicketOverview extends App.Controller
valid_user_ids.push user_id
group.valid_user_ids = valid_user_ids
###
users = [
App.User.find(2),
App.User.find(2),
App.User.find(2),
]
macros = [
{
name: 'Close Beispiel für eine besonders'
},
{
name: 'Close Beispiel für eine besonders'
},
{
name: 'Close Beispiel für eine besonders'
},
{
name: 'Close Beispiel für eine besonders'
},
{
name: 'Close Beispiel für eine besonders'
},
{
name: 'Close Beispiel für eine besonders'
},
{
name: 'Close Beispiel für eine besonders'
},
{
name: 'Close & Tag as Spam'
},
{
name: 'Close & Reply we\'re on Holidays'
},
{
name: 'Escalate to 2nd level'
},
{
name: '1st Close'
},
]
###
@batchAssignInner.html $(App.view('ticket_overview/batch_overlay_user_group')(
users: users
groups: groups
@ -1036,23 +994,30 @@ class Table extends App.Controller
show: true
)
@navigate ticket.uiUrl()
callbackTicketTitleAdd = (value, object, attribute, attributes, refObject) ->
callbackTicketTitleAdd = (value, object, attribute, attributes) ->
attribute.title = object.title
value
callbackLinkToTicket = (value, object, attribute, attributes, refObject) ->
callbackLinkToTicket = (value, object, attribute, attributes) ->
attribute.link = object.uiUrl()
value
callbackUserPopover = (value, object, attribute, attributes, refObject) ->
return value if !refObject
callbackUserPopover = (value, object, attribute, attributes) ->
return value if !object
refObjectId = undefined
if attribute.name is 'customer_id'
refObjectId = object.customer_id
if attribute.name is 'owner_id'
refObjectId = object.owner_id
return value if !refObjectId
attribute.class = 'user-popover'
attribute.data =
id: refObject.id
id: refObjectId
value
callbackOrganizationPopover = (value, object, attribute, attributes, refObject) ->
return value if !refObject
callbackOrganizationPopover = (value, object, attribute, attributes) ->
return value if !object
return value if !object.organization_id
attribute.class = 'organization-popover'
attribute.data =
id: refObject.id
id: object.organization_id
value
callbackCheckbox = (id, checked, e) =>
if @$('table').find('input[name="bulk"]:checked').length == 0
@ -1089,7 +1054,7 @@ class Table extends App.Controller
headers.unshift(0)
headers[0] = attribute
headers
callbackIcon = (value, object, attribute, header, refObject) ->
callbackIcon = (value, object, attribute, header) ->
value = ' '
attribute.class = object.iconClass()
attribute.link = ''

View file

@ -56,7 +56,7 @@ class Index extends App.ControllerSubContent
header.push attribute
header
callbackAttributes = (value, object, attribute, header, refObject) ->
callbackAttributes = (value, object, attribute, header) ->
text = App.i18n.translateInline('View from user\'s perspective')
value = ' '
attribute.raw = ' <span class="btn btn--primary btn--table switchView" title="' + text + '">' + App.Utils.icon('switchView') + text + '</span>'

View file

@ -9,23 +9,30 @@ class App.TicketList extends App.Controller
openTicket = (id,e) =>
ticket = App.Ticket.findNative(id)
@navigate ticket.uiUrl()
callbackTicketTitleAdd = (value, object, attribute, attributes, refObject) ->
callbackTicketTitleAdd = (value, object, attribute, attributes) ->
attribute.title = object.title
value
callbackLinkToTicket = (value, object, attribute, attributes, refObject) ->
callbackLinkToTicket = (value, object, attribute, attributes) ->
attribute.link = object.uiUrl()
value
callbackUserPopover = (value, object, attribute, attributes, refObject) ->
return value if !refObject
callbackUserPopover = (value, object, attribute, attributes) ->
return value if !object
refObjectId = undefined
if attribute.name is 'customer_id'
refObjectId = object.customer_id
if attribute.name is 'owner_id'
refObjectId = object.owner_id
return value if !refObjectId
attribute.class = 'user-popover'
attribute.data =
id: refObject.id
id: refObjectId
value
callbackOrganizationPopover = (value, object, attribute, attributes, refObject) ->
return value if !refObject
callbackOrganizationPopover = (value, object, attribute, attributes) ->
return value if !object
return value if !object.organization_id
attribute.class = 'organization-popover'
attribute.data =
id: refObject.id
id: object.organization_id
value
callbackIconHeader = (headers) ->
@ -39,7 +46,8 @@ class App.TicketList extends App.Controller
headers.unshift(0)
headers[0] = attribute
headers
callbackIcon = (value, object, attribute, header, refObject) ->
callbackIcon = (value, object, attribute, header) ->
value = ' '
attribute.class = object.iconClass()
attribute.link = ''

View file

@ -9,58 +9,57 @@
#= require_tree ./lib/app_post
class App extends Spine.Controller
@viewPrint: (object, attribute_name, attributes) ->
@viewPrint: (object, attributeName, attributes) ->
if !attributes
attributes = {}
if object.constructor.attributesGet
attributes = object.constructor.attributesGet()
attribute_config = attributes[attribute_name]
value = object[attribute_name]
valueRef = undefined
attributeConfig = attributes[attributeName]
value = object[attributeName]
valueRef = undefined
# check if relation is requested
if !attribute_config
attribute_name_new = "#{attribute_name}_id"
attribute_config = attributes[attribute_name_new]
if attribute_config
attribute_name = attribute_name_new
if object[attribute_name]
if !attributeConfig
attributeNameNew = "#{attributeName}_id"
attributeConfig = attributes[attributeNameNew]
if attributeConfig
attributeName = attributeNameNew
if object[attributeName]
valueRef = value
value = object[attribute_name]
value = object[attributeName]
# in case of :: key, get the sub value
if !value
parts = attribute_name.split('::')
parts = attributeName.split('::')
if parts[0] && parts[1] && object[ parts[0] ]
value = object[ parts[0] ][ parts[1] ]
# if we have no config, get output this way
if !attribute_config
if !attributeConfig
return @viewPrintItem(value)
# check if valueRef already exists, no lookup needed later
if !valueRef
attribute_name_without_ref = attribute_name.substr(attribute_name.length-3, attribute_name.length)
if attribute_name_without_ref is '_id'
attribute_name_without_ref = attribute_name.substr(0, attribute_name.length-3)
if object[attribute_name_without_ref]
valueRef = object[attribute_name_without_ref]
if attributeName.substr(attributeName.length-3, attributeName.length) is '_id'
attributeNameWithoutRef = attributeName.substr(0, attributeName.length-3)
if object[attributeNameWithoutRef]
valueRef = object[attributeNameWithoutRef]
@viewPrintItem(value, attribute_config, valueRef)
@viewPrintItem(value, attributeConfig, valueRef)
# define print name helper
@viewPrintItem: (item, attribute_config = {}, valueRef) ->
@viewPrintItem: (item, attributeConfig = {}, valueRef) ->
return '-' if item is undefined
return '-' if item is ''
return item if item is null
result = item
# lookup relation
if attribute_config.relation || valueRef
if attributeConfig.relation || valueRef
if valueRef
item = valueRef
else
item = App[attribute_config.relation].find(item)
item = App[attributeConfig.relation].find(item)
# if date is a object, get name of the object
isObject = false
@ -74,57 +73,57 @@ class App extends Spine.Controller
result = item.name
# execute callback on content
if attribute_config.callback
result = attribute_config.callback(result, attribute_config)
if attributeConfig.callback
result = attributeConfig.callback(result, attributeConfig)
# text2html in textarea view
isHtmlEscape = false
if attribute_config.tag is 'textarea'
if attributeConfig.tag is 'textarea'
isHtmlEscape = true
result = App.Utils.text2html(result)
# remember, html snippets are already escaped
else if attribute_config.tag is 'richtext'
else if attributeConfig.tag is 'richtext'
isHtmlEscape = true
# fillup options
if !_.isEmpty(attribute_config.options)
if attribute_config.options[result]
result = attribute_config.options[result]
if !_.isEmpty(attributeConfig.options)
if attributeConfig.options[result]
result = attributeConfig.options[result]
# transform boolean
if attribute_config.tag is 'boolean'
if attributeConfig.tag is 'boolean'
if result is true
result = 'yes'
else if result is false
result = 'no'
# translate content
if attribute_config.translate || (isObject && item.translate && item.translate())
if attributeConfig.translate || (isObject && item.translate && item.translate())
isHtmlEscape = true
result = App.i18n.translateContent(result)
# transform date
if attribute_config.tag is 'date'
if attributeConfig.tag is 'date'
isHtmlEscape = true
result = App.i18n.translateDate(result)
# transform input tel|url to make it clickable
if attribute_config.tag is 'input'
if attribute_config.type is 'tel'
if attributeConfig.tag is 'input'
if attributeConfig.type is 'tel'
result = "<a href=\"#{App.Utils.phoneify(result)}\">#{App.Utils.htmlEscape(result)}</a>"
else if attribute_config.type is 'url'
else if attributeConfig.type is 'url'
result = App.Utils.linkify(result)
else
result = App.Utils.htmlEscape(result)
isHtmlEscape = true
# use pretty time for datetime
else if attribute_config.tag is 'datetime'
else if attributeConfig.tag is 'datetime'
isHtmlEscape = true
timestamp = App.i18n.translateTimestamp(result)
escalation = false
cssClass = attribute_config.class || ''
cssClass = attributeConfig.class || ''
if cssClass.match 'escalation'
escalation = true
humanTime = App.PrettyDate.humanTime(result, escalation)
@ -139,8 +138,8 @@ class App extends Spine.Controller
template = (params = {}) ->
# define print name helper
params.P = (object, attribute_name, attributes) ->
App.viewPrint(object, attribute_name, attributes)
params.P = (object, attributeName, attributes) ->
App.viewPrint(object, attributeName, attributes)
# define date format helper
params.date = (time) ->

View file

@ -13,37 +13,36 @@
<td>
<%- ticket.customer.avatar("50", "", "userInfo-avatar") %>
<h2 style="margin-top: 0px;"><a href="<%- ticket.uiUrl() %>" data-type="edit"><%= ticket.title %></a></h2>
<div class="horizontal">
<div class="vertical flex">
<table style="width: 100%;">
<tr>
<td style="width: 25%;"><label><%- @T( 'Number' ) %></label></td><td> <%- @P( ticket, 'number' ) %></td>
<td style="width: 25%;"><label><%- @T('Number') %></label></td><td> <%- @P(ticket, 'number') %></td>
</tr>
<tr>
<td><label><%- @T( 'State' ) %></label></td><td> <%- @P( ticket, 'state' ) %></td>
<td><label><%- @T('State') %></label></td><td> <%- @P(ticket, 'state') %></td>
</tr>
<tr>
<td><label><%- @T( 'Group' ) %></label></td><td> <%- @P( ticket, 'group' ) %></td>
<td><label><%- @T('Group') %></label></td><td> <%- @P(ticket, 'group') %></td>
</tr>
<tr>
<td><label><%- @T( 'Customer' ) %></label></td><td> <%- @P( ticket, 'customer' ) %></td>
<td><label><%- @T('Customer') %></label></td><td> <%- @P(ticket, 'customer') %></td>
</tr>
</table>
</div>
<div class="vertical flex">
<table style="width: 100%;">
<tr>
<td style="width: 25%;"><label><%- @T( 'Erstellt' ) %></label></td><td> <%- @P( ticket, 'created_at' ) %></td>
<td style="width: 25%;"><label><%- @T('Erstellt') %></label></td><td> <%- @P(ticket, 'created_at') %></td>
</tr>
<tr>
<td><label><%- @T( 'Priority' ) %></label></td><td> <%- @P( ticket, 'priority' ) %></td>
<td><label><%- @T('Priority') %></label></td><td> <%- @P(ticket, 'priority') %></td>
</tr>
<tr>
<td><label><%- @T( 'Owner' ) %></label></td><td> <%- @P( ticket, 'owner' ) %></td>
<td><label><%- @T('Owner') %></label></td><td> <%- @P(ticket, 'owner') %></td>
</tr>
<tr>
<td><label><%- @T( 'Organization' ) %></label></td><td> <%- @P( ticket, 'organization' ) %></td>
<td><label><%- @T('Organization') %></label></td><td> <%- @P(ticket, 'organization') %></td>
</tr>
</table>
</div>

View file

@ -17,103 +17,24 @@
<% if @radio: %>
<th style="width: 40px" class="table-radio"></th>
<% end %>
<% for item, i in @header: %>
<th class="js-tableHead<%= " #{ item.className }" if item.className %><%= " align-#{ item.align }" if item.align %>" style="<% if item.displayWidth: %>width:<%= item.displayWidth %>px<% end %>" data-column-key="<%= item.name %>">
<% for header, i in @headers: %>
<th class="js-tableHead<%= " #{ header.className }" if header.className %><%= " align-#{ header.align }" if header.align %>" style="<% if header.displayWidth: %>width:<%= header.displayWidth %>px<% end %>" data-column-key="<%= header.name %>">
<div class="table-column-head<%= ' js-sort' if @tableId %>">
<div class="table-column-title">
<%- @T(item.display) %>
<%- @T(header.display) %>
</div>
<div class="table-column-sortIcon">
<% if item.sortOrderIcon: %>
<%- @Icon(item.sortOrderIcon[0], item.sortOrderIcon[1]) %>
<% if header.sortOrderIcon: %>
<%- @Icon(header.sortOrderIcon[0], header.sortOrderIcon[1]) %>
<% end %>
</div>
</div>
<% if @tableId && !item.unresizable && i < @header.length - 1: %>
<% if @tableId && !header.unresizable && i < @headers.length - 1: %>
<div class="table-col-resize js-col-resize"></div>
<% end %>
</th>
<% end %>
</tr>
</thead>
<tbody>
<% position = 0 %>
<% length = @header.length %>
<% if @checkbox || @radio: %>
<% length++ %>
<% end %>
<% groupLast = '' %>
<% for object in @objects: %>
<% if @groupBy: %>
<% groupByName = @P(object, @groupBy, @attributes) %>
<% if groupLast isnt groupByName: %>
<tr class=""><td colspan="<%= length %>"><b><%= groupByName %></b></td></tr>
<% groupLast = groupByName %>
<% end %>
<% end %>
<% position++ %>
<tr class="item<%= ' is-inactive' if object.active is false %>" data-id="<%= object.id %>" data-position="<%= position %>" >
<% if @sortable: %>
<td class="table-draggable"><%- @Icon('draggable') %></td>
<% end %>
<% if @checkbox: %>
<td class="table-checkbox js-checkbox-field">
<label class="checkbox-replacement">
<input type="checkbox" value="<%= object.id %>" name="bulk">
<%- @Icon('checkbox', 'icon-unchecked') %>
<%- @Icon('checkbox-checked', 'icon-checked') %>
</label>
</td>
<% end %>
<% if @radio: %>
<td class="table-radio">
<label class="radio-replacement">
<input type="radio" value="<%= object.id %>" name="radio">
<%- @Icon('radio', 'icon-unchecked') %>
<%- @Icon('radio-checked', 'icon-checked') %>
</label>
</td>
<% end %>
<% for item in @header: %>
<% value = @P(object, item.name, @attributes) %>
<% if @callbacks: %>
<% if item.name.substr(item.name.length-3, item.name.length) is '_id' && object[ item.name.substr(0, item.name.length-3) ]: %>
<% refObject = object[ item.name.substr(0, item.name.length-3) ] %>
<% end %>
<% for attribute, callbacksAll of @callbacks: %>
<% if attribute is item.name: %>
<% for callback in callbacksAll: %>
<% value = callback(value, object, item, @header, refObject) %>
<% end %>
<% end %>
<% end %>
<% end %>
<td<%- " class='#{ item.parentClass }'" if item.parentClass %><%- " title='#{ item.title }'" if item.title %><%- " style='text-align:#{ item.align }'" if item.align %>>
<% if item.name is 'icon': %>
<%- @Icon('task-state', item.class) %>
<% else if item.icon: %>
<%- @Icon(item.icon) %>
<% else: %>
<% if item.link: %>
<a href="<%- item.link %>" <% if item.target: %>target="<%= item.target %>"<% end %>>
<% end %>
<% if item.raw: %>
<%- item.raw %>
<% else: %>
<% if item.class || item.data: %>
<span <% if item.class: %>class="<%= item.class %>"<% end %> <% if item.data: %><% for data_key, data_item of item.data: %>data-<%- data_key %>="<%= data_item %>" <% end %><% end %>>
<% end %>
<%- value %>
<% if item.class || item.data: %>
</span>
<% end %>
<% end %>
<% if item.link: %></a><% end %>
<% end %>
</td>
<% end %>
</tr>
<% end %>
</tbody>
<tbody><%- @tableBody %></tbody>
</table>

View file

@ -0,0 +1,56 @@
<tr class="item<%= ' is-inactive' if @object.active is false %>" data-id="<%= @object.id %>" data-position="<%= @position %>">
<% if @sortable: %>
<td class="table-draggable"><%- @Icon('draggable') %></td>
<% end %>
<% if @checkbox: %>
<td class="table-checkbox js-checkbox-field">
<label class="checkbox-replacement">
<input type="checkbox" value="<%= @object.id %>" name="bulk">
<%- @Icon('checkbox', 'icon-unchecked') %>
<%- @Icon('checkbox-checked', 'icon-checked') %>
</label>
</td>
<% end %>
<% if @radio: %>
<td class="table-radio">
<label class="radio-replacement">
<input type="radio" value="<%= @object.id %>" name="radio">
<%- @Icon('radio', 'icon-unchecked') %>
<%- @Icon('radio-checked', 'icon-checked') %>
</label>
</td>
<% end %>
<% for header in @headers: %>
<% value = @P(@object, header.name, @attributes) %>
<% if @callbacks: %>
<% for attribute, callbacksAll of @callbacks: %>
<% if attribute is header.name: %>
<% for callback in callbacksAll: %>
<% value = callback(value, @object, header, @headers) %>
<% end %>
<% end %>
<% end %>
<% end %>
<td<%- " class='#{ header.parentClass }'" if header.parentClass %><%- " title='#{ header.title }'" if header.title %><%- " style='text-align:#{ header.align }'" if header.align %>>
<% if header.name is 'icon': %>
<%- @Icon('task-state', header.class) %>
<% else if header.icon: %>
<%- @Icon(header.icon) %>
<% else: %>
<% if header.link: %>
<a href="<%- header.link %>" <% if header.target: %>target="<%= header.target %>"<% end %>>
<% end %>
<% if header.raw: %>
<%- header.raw %>
<% else: %>
<% if header.class || header.data: %>
<span <% if header.class: %>class="<%= header.class %>"<% end %> <% if header.data: %><% for data_key, data_header of header.data: %>data-<%- data_key %>="<%= data_header %>" <% end %><% end %>>
<% end %>
<%- value %>
<% if header.class || header.data: %></span><% end %>
<% end %>
<% if header.link: %></a><% end %>
<% end %>
</td>
<% end %>
</tr>

View file

@ -0,0 +1,3 @@
<tr>
<td colspan="<%= @columnsLength %>"><b><%= @groupByName %></b></td>
</tr>

View file

@ -24,18 +24,18 @@
<div class="horizontal two-columns">
<div class="column">
<label>#</label>
<div class="u-textTruncate"><%- @P( @ticket, 'number' ) %></div>
<div class="u-textTruncate"><%- @P(@ticket, 'number') %></div>
</div>
<div class="column">
<label><%- @T( 'Priority' ) %></label>
<div class="u-textTruncate"><%- @P( @ticket, 'priority' ) %></div>
<label><%- @T('Priority') %></label>
<div class="u-textTruncate"><%- @P(@ticket, 'priority') %></div>
</div>
<div class="column">
<label><%- @T( 'Created' ) %></label>
<div class="u-textTruncate"><%- @P( @ticket, 'created_at' ) %></div>
<label><%- @T('Created') %></label>
<div class="u-textTruncate"><%- @P(@ticket, 'created_at') %></div>
</div>
<div class="column">
<label><%- @T( 'Group' ) %></label>
<div class="u-textTruncate"><%- @P( @ticket, 'group' ) %></div>
<label><%- @T('Group') %></label>
<div class="u-textTruncate"><%- @P(@ticket, 'group') %></div>
</div>
</div>

View file

@ -5,30 +5,30 @@
<% for row in @userData: %>
<% if @user[row.name]: %>
<div class="popover-block">
<label><%- @T( row.display ) %></label>
<%- @P( @user, row.name ) %>
<label><%- @T(row.display) %></label>
<%- @P(@user, row.name) %>
</div>
<% end %>
<% end %>
<% if !_.isEmpty(@user['accounts']): %>
<div class="popover-block">
<label><%- @T( 'Linked Accounts' ) %></label>
<label><%- @T('Linked Accounts') %></label>
<% for account of @user['accounts']: %>
<a href="<%= @user['accounts'][account]['link'] %>" target="_blank"><%= account %></a>
<% end %>
</div>
<% end %>
<% if !_.isEmpty( @user['links'] ): %>
<% if !_.isEmpty(@user['links']): %>
<% for link in @user['links']: %>
<div class="popover-block">
<label><%- @T( link['title'] ) %></label>
<label><%- @T(link['title']) %></label>
<% for item in link['items']: %>
<% if item['url']: %>
<a href="<%= item['url'] %>" title="<%- @Ti( item['title'] ) %>" style="<%= item['style'] %>" data-type="<%= item['data'] %>" class="<%= item['class'] %>" <% if link.new_window: %>target="_blank"<% end %>>
<a href="<%= item['url'] %>" title="<%- @Ti(item['title']) %>" style="<%= item['style'] %>" data-type="<%= item['data'] %>" class="<%= item['class'] %>" <% if link.new_window: %>target="_blank"<% end %>>
<% else: %>
<span title="<%- @Ti( item['title'] ) %>" style="<%= item['style'] %>" data-type="<%= item['data'] %>" class="<%= item['class'] %>">
<span title="<%- @Ti(item['title']) %>" style="<%= item['style'] %>" data-type="<%= item['data'] %>" class="<%= item['class'] %>">
<% end %>
<%- @T( item['name'] ) %> <% if item['count'] isnt undefined: %><span class="count">(<%= item['count'] %>)</span><% end %>
<%- @T(item['name']) %> <% if item['count'] isnt undefined: %><span class="count">(<%= item['count'] %>)</span><% end %>
<% if item['url']: %>
</a>
<% else: %>