diff --git a/app/assets/javascripts/app/controllers/_application_controller_table.coffee b/app/assets/javascripts/app/controllers/_application_controller_table.coffee index 21fcab3e9..2b59a986f 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_table.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_table.coffee @@ -133,6 +133,8 @@ class App.ControllerTable extends App.Controller customOrderDirection: undefined customOrderBy: undefined + frontendTimeUpdateExecute: true + bindCol: {} bindRow: {} @@ -269,6 +271,7 @@ class App.ControllerTable extends App.Controller @currentRows = newCurrentRows @log 'debug', 'table.fullRender.contentRemoved', removePositions, addPositions @renderPager(@el, true) + @frontendTimeUpdateElement(@el) if @frontendTimeUpdateExecute is true return ['fullRender.contentRemoved', removePositions, addPositions] if newRows.length isnt @currentRows.length @@ -304,6 +307,7 @@ class App.ControllerTable extends App.Controller else @currentRows = clone(rows) container.find('.js-tableBody').html(rows) + @frontendTimeUpdateElement(container) if @frontendTimeUpdateExecute is true @renderPager(container) diff --git a/app/assets/javascripts/app/controllers/report.coffee b/app/assets/javascripts/app/controllers/report.coffee index 90c3c9d1f..c8cc04620 100644 --- a/app/assets/javascripts/app/controllers/report.coffee +++ b/app/assets/javascripts/app/controllers/report.coffee @@ -108,33 +108,40 @@ class Graph extends App.ControllerContent @render() - render: => + update: (data) => - update = (data) => + # show only selected lines + dataNew = {} + for key, value of data.data + if @params.backendSelected[key] is true + dataNew[key] = value + @ui.storeParams() - # show only selected lines - dataNew = {} - for key, value of data.data - if @params.backendSelected[key] is true - dataNew[key] = value - @ui.storeParams() + if !@lastNewData + @lastNewData = {} - if !@lastNewData - @lastNewData = {} + return if @lastNewData && JSON.stringify(dataNew) is JSON.stringify(@lastNewData) + @lastNewData = dataNew - return if @lastNewData && JSON.stringify(dataNew) is JSON.stringify(@lastNewData) - @lastNewData = dataNew - - @draw(dataNew) - t = new Date - @el.find('#download-chart').html(t.toString()) - new Download( + @draw(dataNew) + t = new Date + @el.find('#download-chart').html(t.toString()) + if @downloadWidget + @downloadWidget.update( + config: @config + params: @params + ui: @ui + ) + else + @downloadWidget = new Download( el: @el.find('.js-dataDownload') config: @config params: @params ui: @ui ) + render: => + url = "#{@apiPath}/reports/generate" interval = 5 * 60000 if @params.timeRange is 'year' @@ -142,9 +149,9 @@ class Graph extends App.ControllerContent if @params.timeRange is 'month' interval = 60000 if @params.timeRange is 'week' - interval = 40000 + interval = 50000 if @params.timeRange is 'day' - interval = 20000 + interval = 30000 if @params.timeRange is 'realtime' interval = 10000 @@ -164,7 +171,7 @@ class Graph extends App.ControllerContent ) processData: true success: (data) => - update(data) + @update(data) @delay(@render, interval, 'report-update', 'page') ) @@ -215,7 +222,7 @@ class Graph extends App.ControllerContent class Download extends App.Controller events: - 'click .js-dataDownloadBackendSelector': 'tableUpdate' + 'click .js-dataDownloadBackendSelector': 'selectBackend' constructor: (data) -> @@ -225,7 +232,24 @@ class Download extends App.Controller super @render() - render: -> + selectBackend: (e) => + e.preventDefault() + @el.find('.js-dataDownloadBackendSelector').parent().removeClass('active') + $(e.target).parent().addClass('active') + @profileSelectedId = $(e.target).data('profile-id') + @params.downloadBackendSelected = $(e.target).data('backend') + @ui.storeParams() + @table = false + @render() + + update: => + @render() + + render: => + + if !@contentRendered + @contentRendered = true + @html(App.view('report/download_content')()) reports = [] @@ -244,44 +268,84 @@ class Download extends App.Controller @profileSelectedId = key profiles.push App.ReportProfile.find(key) - @html App.view('report/download_header')( + downloadHeaderHtml = App.view('report/download_header')( reports: reports profiles: profiles downloadBackendSelected: @params.downloadBackendSelected metric: @config.metric[@params.metric] ) + if downloadHeaderHtml isnt @downloadHeaderHtml + @el.find('.js-dataDownloadHeader').html(downloadHeaderHtml) + @downloadHeaderHtml = downloadHeaderHtml @tableUpdate() - tableUpdate: (e) => - if e - e.preventDefault() - @el.find('.js-dataDownloadBackendSelector').parent().removeClass('active') - $(e.target).parent().addClass('active') - @profileSelectedId = $(e.target).data('profile-id') - @params.downloadBackendSelected = $(e.target).data('backend') - @ui.storeParams() + tableRender: (tickets, count) => + if _.isEmpty(tickets) + @$('.js-dataDownloadButton').html('') + @$('.js-dataDownloadTable').html('') + return - table = (tickets, count) => - url = '#ticket/zoom/' - if App.Config.get('import_mode') - url = App.Config.get('import_otrs_endpoint') + '/index.pl?Action=AgentTicketZoom;TicketID=' - if _.isEmpty(tickets) - @el.find('.js-dataDownloadTable').html('') - else - profile_id = 0 - for key, value of @params.profileSelected - if value - profile_id = key - downloadUrl = "#{@apiPath}/reports/sets?sheet=true;metric=#{@params.metric};year=#{@params.year};month=#{@params.month};week=#{@params.week};day=#{@params.day};timeRange=#{@params.timeRange};profile_id=#{profile_id};downloadBackendSelected=#{@params.downloadBackendSelected}" - html = App.view('report/download_list')( - tickets: tickets - count: count - url: url - download: downloadUrl - ) - @el.find('.js-dataDownloadTable').html(html) + profile_id = 0 + for key, value of @params.profileSelected + if value + profile_id = key + downloadUrl = "#{@apiPath}/reports/sets?sheet=true;metric=#{@params.metric};year=#{@params.year};month=#{@params.month};week=#{@params.week};day=#{@params.day};timeRange=#{@params.timeRange};profile_id=#{profile_id};downloadBackendSelected=#{@params.downloadBackendSelected}" + @$('.js-dataDownloadButton').html(App.view('report/download_button')( + count: count + downloadUrl: downloadUrl + )) + openTicket = (id,e) => + ticket = App.Ticket.findNative(id) + @navigate ticket.uiUrl() + callbackTicketTitleAdd = (value, object, attribute, attributes) -> + attribute.title = object.title + value + callbackLinkToTicket = (value, object, attribute, attributes) -> + attribute.link = object.uiUrl() + value + callbackIconHeader = (headers) -> + attribute = + name: 'icon' + display: '' + translation: false + width: '28px' + displayWidth:28 + unresizable: true + headers.unshift(0) + headers[0] = attribute + headers + callbackIcon = (value, object, attribute, header) -> + value = ' ' + attribute.class = object.iconClass() + attribute.link = '' + attribute.title = object.iconTitle() + value + + params = + el: @el.find('.js-dataDownloadTable') + model: App.Ticket + objects: tickets + overviewAttributes: ['number', 'title', 'state', 'group', 'created_at'] + bindRow: + events: + 'click': openTicket + callbackHeader: [ callbackIconHeader ] + callbackAttributes: + icon: + [ callbackIcon ] + title: + [ callbackLinkToTicket, callbackTicketTitleAdd ] + number: + [ callbackLinkToTicket, callbackTicketTitleAdd ] + + if !@table + @table = new App.ControllerTable(params) + else + @table.update(objects: tickets) + + tableUpdate: => @ajax( id: 'report_download' type: 'POST' @@ -298,15 +362,14 @@ class Download extends App.Controller downloadBackendSelected: @params.downloadBackendSelected ) processData: true - success: (data) -> + success: (data) => App.Collection.loadAssets(data.assets) ticket_collection = [] if data.ticket_ids for record_id in data.ticket_ids - ticket = App.Ticket.fullLocal( record_id ) + ticket = App.Ticket.fullLocal(record_id) ticket_collection.push ticket - - table(ticket_collection, data.count) + @tableRender(ticket_collection, data.count) ) class TimeRangePicker extends App.Controller diff --git a/app/assets/javascripts/app/index.coffee b/app/assets/javascripts/app/index.coffee index 3e6211d9b..d9fbb2028 100644 --- a/app/assets/javascripts/app/index.coffee +++ b/app/assets/javascripts/app/index.coffee @@ -12,8 +12,8 @@ class App extends Spine.Controller helper = # define print name helper - P: (object, attributeName, attributes) -> - App.viewPrint(object, attributeName, attributes) + P: (object, attributeName, attributes, table = false) -> + App.viewPrint(object, attributeName, attributes, table) # define date format helper date: (time) -> @@ -136,7 +136,7 @@ class App extends Spine.Controller return marked(string) App.i18n.translateContent(string) - @viewPrint: (object, attributeName, attributes) -> + @viewPrint: (object, attributeName, attributes, table) -> if !attributes attributes = {} if object.constructor.attributesGet @@ -172,10 +172,10 @@ class App extends Spine.Controller if object[attributeNameWithoutRef] valueRef = object[attributeNameWithoutRef] - @viewPrintItem(value, attributeConfig, valueRef) + @viewPrintItem(value, attributeConfig, valueRef, table) # define print name helper - @viewPrintItem: (item, attributeConfig = {}, valueRef) -> + @viewPrintItem: (item, attributeConfig = {}, valueRef, table) -> return '-' if item is undefined return '-' if item is '' return item if item is null @@ -238,7 +238,7 @@ class App extends Spine.Controller # transform date if attributeConfig.tag is 'date' isHtmlEscape = true - resultLocal = App.i18n.translateDate(resultLocal) + resultLocal = App.i18n.translateDate(resultLocal) # transform input tel|url to make it clickable if attributeConfig.tag is 'input' @@ -258,8 +258,10 @@ class App extends Spine.Controller cssClass = attributeConfig.class || '' if cssClass.match 'escalation' escalation = true - humanTime = App.PrettyDate.humanTime(resultLocal, escalation) - resultLocal = "" + humanTime = '' + if !table + humanTime = App.PrettyDate.humanTime(resultLocal, escalation) + resultLocal = "" if !isHtmlEscape && typeof resultLocal is 'string' resultLocal = App.Utils.htmlEscape(resultLocal) 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 1aa07f841..711fda2eb 100644 --- a/app/assets/javascripts/app/views/generic/table_row.jst.eco +++ b/app/assets/javascripts/app/views/generic/table_row.jst.eco @@ -21,7 +21,7 @@ <% end %> <% for header in @headers: %> - <% value = @P(@object, header.name, @attributes) %> + <% value = @P(@object, header.name, @attributes, true) %> <% if @callbacks: %> <% for attribute, callbacksAll of @callbacks: %> <% if attribute is header.name: %> diff --git a/app/assets/javascripts/app/views/report/download_button.jst.eco b/app/assets/javascripts/app/views/report/download_button.jst.eco new file mode 100644 index 000000000..715a38609 --- /dev/null +++ b/app/assets/javascripts/app/views/report/download_button.jst.eco @@ -0,0 +1 @@ +<%- @Icon('download') %><%- @T('Download %s record(s)', @count) %> diff --git a/app/assets/javascripts/app/views/report/download_content.jst.eco b/app/assets/javascripts/app/views/report/download_content.jst.eco new file mode 100644 index 000000000..01965b7bc --- /dev/null +++ b/app/assets/javascripts/app/views/report/download_content.jst.eco @@ -0,0 +1,6 @@ +
+
+
+
+
+
\ No newline at end of file diff --git a/app/assets/javascripts/app/views/report/download_header.jst.eco b/app/assets/javascripts/app/views/report/download_header.jst.eco index 7769d2b54..8998b0067 100644 --- a/app/assets/javascripts/app/views/report/download_header.jst.eco +++ b/app/assets/javascripts/app/views/report/download_header.jst.eco @@ -1,14 +1,9 @@ -
- -
\ No newline at end of file + <% end %> + diff --git a/app/assets/javascripts/app/views/report/download_list.jst.eco b/app/assets/javascripts/app/views/report/download_list.jst.eco deleted file mode 100644 index f22dc8983..000000000 --- a/app/assets/javascripts/app/views/report/download_list.jst.eco +++ /dev/null @@ -1,24 +0,0 @@ -<%- @Icon('download') %><%- @T('Download %s record(s)', @count) %> -
- - - - - - - - - - - -<% for ticket in @tickets: %> - - - - - - - -<% end %> - -
<%- @T('Number') %><%- @T('Title') %><%- @T('State') %><%- @T('Group') %><%- @T('Created') %>
target="_blank"<% end %> href="<%= @url %><%= ticket.id %>"><%- @P(ticket, 'number') %><%- @P(ticket, 'title') %><%- @P(ticket, 'state') %><%- @P(ticket, 'group') %><%- @P(ticket, 'created_at') %>
diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index 01c36af9f..6cba59c42 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -211,22 +211,26 @@ class ReportsController < ApplicationController row = 2 result[:ticket_ids].each do |ticket_id| - ticket = Ticket.lookup(id: ticket_id) - row += 1 - worksheet.write(row, 0, ticket.number) - worksheet.write(row, 1, ticket.title) - worksheet.write(row, 2, ticket.state.name) - worksheet.write(row, 3, ticket.priority.name) - worksheet.write(row, 4, ticket.group.name) - worksheet.write(row, 5, ticket.owner.fullname) - worksheet.write(row, 6, ticket.customer.fullname) - worksheet.write(row, 7, ticket.try(:organization).try(:name)) - worksheet.write(row, 8, ticket.create_article_type.name) - worksheet.write(row, 9, ticket.create_article_sender.name) - worksheet.write(row, 10, ticket.tag_list.join(',')) - worksheet.write(row, 11, ticket.created_at) - worksheet.write(row, 12, ticket.updated_at) - worksheet.write(row, 13, ticket.close_at) + begin + ticket = Ticket.lookup(id: ticket_id) + row += 1 + worksheet.write(row, 0, ticket.number) + worksheet.write(row, 1, ticket.title) + worksheet.write(row, 2, ticket.state.name) + worksheet.write(row, 3, ticket.priority.name) + worksheet.write(row, 4, ticket.group.name) + worksheet.write(row, 5, ticket.owner.fullname) + worksheet.write(row, 6, ticket.customer.fullname) + worksheet.write(row, 7, ticket.try(:organization).try(:name)) + worksheet.write(row, 8, ticket.create_article_type.name) + worksheet.write(row, 9, ticket.create_article_sender.name) + worksheet.write(row, 10, ticket.tag_list.join(',')) + worksheet.write(row, 11, ticket.created_at) + worksheet.write(row, 12, ticket.updated_at) + worksheet.write(row, 13, ticket.close_at) + rescue => e + Rails.logger.error "SKIP: #{e.message}" + end end workbook.close diff --git a/lib/report/base.rb b/lib/report/base.rb index ada98a0f1..b43801452 100644 --- a/lib/report/base.rb +++ b/lib/report/base.rb @@ -10,7 +10,7 @@ class Report::Base # :selector def self.history_count(params) - history_object = History::Object.lookup( name: params[:object] ) + history_object = History::Object.lookup(name: params[:object]) query, bind_params, tables = Ticket.selector2sql(params[:selector]) diff --git a/lib/report/ticket_generic_time.rb b/lib/report/ticket_generic_time.rb index 0eaba33e2..5372f1166 100644 --- a/lib/report/ticket_generic_time.rb +++ b/lib/report/ticket_generic_time.rb @@ -135,8 +135,8 @@ returns field: params[:params][:field], } - limit = 1000 - if !params[:sheet] + limit = 6000 + if params[:sheet].blank? limit = 100 end @@ -146,6 +146,7 @@ returns end result = SearchIndexBackend.selectors(['Ticket'], selector, limit, nil, aggs_interval) + return result if params[:sheet].present? assets = {} result[:ticket_ids].each do |ticket_id| ticket_full = Ticket.find(ticket_id) diff --git a/lib/report/ticket_moved.rb b/lib/report/ticket_moved.rb index 03f75b546..88e4de29e 100644 --- a/lib/report/ticket_moved.rb +++ b/lib/report/ticket_moved.rb @@ -123,6 +123,7 @@ returns } local_params = defaults.merge(local_params) result = history(local_params) + return result if params[:sheet].present? assets = {} result[:ticket_ids].each do |ticket_id| ticket_full = Ticket.find(ticket_id) diff --git a/lib/report/ticket_reopened.rb b/lib/report/ticket_reopened.rb index ef4affd37..9b7f7d5a6 100644 --- a/lib/report/ticket_reopened.rb +++ b/lib/report/ticket_reopened.rb @@ -98,6 +98,7 @@ returns end: params[:range_end], selector: params[:selector] ) + return result if params[:sheet].present? assets = {} result[:ticket_ids].each do |ticket_id| ticket_full = Ticket.find(ticket_id) diff --git a/public/assets/tests/table_extended.js b/public/assets/tests/table_extended.js index 63a8c1476..082861c2f 100644 --- a/public/assets/tests/table_extended.js +++ b/public/assets/tests/table_extended.js @@ -1646,4 +1646,63 @@ test('table new - initial list', function() { equal(el.find('tbody > tr:nth-child(4) > td').length, 0, 'check row 3') + $('#table').append('

table with data 11

') + var el = $('#table-new11') + + App.TicketPriority.refresh([ + { + id: 1, + name: '1 low', + note: 'some note 1', + active: true, + created_at: '2014-06-10T11:17:34.000Z', + }, + { + id: 2, + name: '2 normal', + note: 'some note 2', + active: false, + created_at: '2014-06-10T10:17:34.000Z', + }, + ], {clear: true}) + + var table = new App.ControllerTable({ + el: el, + overviewAttributes: ['name', 'created_at', 'active'], + model: App.TicketPriority, + objects: App.TicketPriority.search({sortBy:'name', order: 'ASC'}), + checkbox: false, + radio: false, + frontendTimeUpdateExecute: false, + }) + //equal(el.find('table').length, 0, 'row count') + //table.render() + equal(el.find('table > thead > tr').length, 1, 'row count') + equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Name', 'check header') + equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Erstellt', 'check header') + equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Aktiv', 'check header') + equal(el.find('tbody > tr:nth-child(1) > td').length, 3, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:first').text().trim(), '1 niedrig', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'true', 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td').length, 3, 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:first').text().trim(), '2 normal', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), '', 'check row 2') + equal(el.find('tbody > tr:nth-child(3) > td').length, 0, 'check row 3') + + result = table.update({sync: true, objects: App.TicketPriority.search({sortBy:'name', order: 'ASC'})}) + equal(result[0], 'noChanges') + + equal(el.find('table > thead > tr').length, 1, 'row count') + equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Name', 'check header') + equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Erstellt', 'check header') + equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Aktiv', 'check header') + equal(el.find('tbody > tr:nth-child(1) > td').length, 3, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:first').text().trim(), '1 niedrig', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'true', 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td').length, 3, 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:first').text().trim(), '2 normal', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), '', 'check row 2') + })