Added preview for ticket selector.

This commit is contained in:
Martin Edenhofer 2015-09-17 03:04:16 +02:00
parent f4b642726e
commit 3fc3ad5e5a
6 changed files with 133 additions and 21 deletions

View file

@ -1,4 +1,4 @@
class App.UiElement.ticket_selector extends App.UiElement.ApplicationUiElement
class App.UiElement.ticket_selector
@render: (attribute, params = {}) ->
# list of attributes
@ -129,25 +129,19 @@ class App.UiElement.ticket_selector extends App.UiElement.ApplicationUiElement
groupAndAttribute = $(e.target).find('option:selected').attr('value')
elementRow = $(e.target).closest('.js-filterElement')
console.log('CHANGE', groupAndAttribute, $(e.target))
@rebuildAttributeSelectors(item, elementRow, groupAndAttribute)
@rebuildOperater(item, elementRow, groupAndAttribute, elements)
@buildValue(item, elementRow, groupAndAttribute, elements)
)
# build inital params
console.log('P', params)
if !_.isEmpty(params.condition)
selectorExists = false
for position of params.condition.attribute
# get stored params
groupAndAttribute = params.condition.attribute[position]
if params.condition[groupAndAttribute]
for groupAndAttribute, meta of params.condition
if groupAndAttribute isnt 'attribute'
selectorExists = true
operator = params.condition[groupAndAttribute].operator
value = params.condition[groupAndAttribute].value
operator = meta.operator
value = meta.value
# get selector rows
elementFirst = item.find('.js-filterElement').first()
@ -163,8 +157,49 @@ class App.UiElement.ticket_selector extends App.UiElement.ApplicationUiElement
# remove first dummy row
if selectorExists
item.find('.js-filterElement').first().remove()
# bind for preview
search = =>
@preview(item)
item.on('change', 'select.form-control', (e) =>
App.Delay.set(
search,
600,
'preview',
)
)
item.on('keyup', 'input.form-control', (e) =>
App.Delay.set(
search,
600,
'preview',
)
)
item
@preview: (item) ->
params = App.ControllerForm.params(item)
# ajax call
App.Ajax.request(
id: 'ticket_selector'
type: 'POST'
url: "#{App.Config.get('api_path')}/tickets/selector"
data: JSON.stringify(params)
processData: true,
success: (data, status, xhr) =>
App.Collection.loadAssets( data.assets )
@ticketTable(data.ticket_ids, data.ticket_count, item)
)
@ticketTable: (ticket_ids, ticket_count, item) =>
item.find('.js-previewCounter').html(ticket_count)
new App.TicketList(
el: item.find('.js-previewTable')
ticket_ids: ticket_ids
)
@getElementConfig: (groupAndAttribute, elements) ->
for elementGroup, elementConfig of elements
for elementKey, elementItem of elementConfig
@ -253,7 +288,8 @@ class App.UiElement.ticket_selector extends App.UiElement.ApplicationUiElement
elementRow.find('.js-operator select').replaceWith(operator)
@humanText: (condition) ->
return [] if _.isEmpty(condition)
none = App.i18n.translateContent('No filter.')
return [none] if _.isEmpty(condition)
rules = []
for position of condition.attribute
@ -263,5 +299,7 @@ class App.UiElement.ticket_selector extends App.UiElement.ApplicationUiElement
selectorExists = true
operator = condition[groupAndAttribute].operator
value = condition[groupAndAttribute].value
rules.push "Where <b>#{groupAndAttribute}</b> #{operator} <b>#{value}</b>."
rules.push "#{App.i18n.translateContent('Where')} <b>#{App.i18n.translateContent(groupAndAttribute)}</b> #{App.i18n.translateContent(operator)} <b>#{App.i18n.translateContent(value)}</b>."
return [none] if _.isEmpty(rules)
rules

View file

@ -3,14 +3,14 @@ class App.Sla extends App.Model
@extend Spine.Model.Ajax
@url: @apiPath + '/slas'
@configure_attributes = [
{ name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, null: false },
{ name: 'condition', display: 'Selector', tag: 'ticket_selector', null: false, note: 'Create rules that single out the tickets for the Service Level Agreement.' },
{ name: 'calendar_id', display: 'Calendar', tag: 'select', relation: 'Calendar', null: false },
{ name: 'sla_times', display: 'SLA Times', tag: 'sla_times', null: true },
{ name: 'created_by_id', display: 'Created by', relation: 'User', readonly: 1 },
{ name: 'created_at', display: 'Created', tag: 'datetime', readonly: 1 },
{ name: 'updated_by_id', display: 'Updated by', relation: 'User', readonly: 1 },
{ name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 },
{ name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, null: false },
{ name: 'condition', display: 'Ticket Selector', tag: 'ticket_selector', null: false, note: 'Create rules that single out the tickets for the Service Level Agreement.' },
{ name: 'calendar_id', display: 'Calendar', tag: 'select', relation: 'Calendar', null: false },
{ name: 'sla_times', display: 'SLA Times', tag: 'sla_times', null: true },
{ name: 'created_by_id', display: 'Created by', relation: 'User', readonly: 1 },
{ name: 'created_at', display: 'Created', tag: 'datetime', readonly: 1 },
{ name: 'updated_by_id', display: 'Updated by', relation: 'User', readonly: 1 },
{ name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 },
]
@configure_delete = true
@configure_overview = [

View file

@ -23,4 +23,8 @@
</div>
</div>
</div>
</div>
<div class="js-preview">
<h3><%- @T('Preview') %><span class="subtitle"> <span class="u-highlight js-previewCounter">?</span> <%- @T('matches') %></span></h3>
<div class="js-previewTable"></div>
</div>

View file

@ -345,6 +345,29 @@ class TicketsController < ApplicationController
}
end
# GET /api/v1/tickets/selector
def selector
return if deny_if_not_role(Z_ROLENAME_ADMIN)
ticket_count, tickets = Ticket.selectors(params[:condition], 6)
assets = {}
ticket_ids = []
if tickets
tickets.each do |ticket|
ticket_ids.push ticket.id
assets = ticket.assets(assets)
end
end
# return result
render json: {
ticket_ids: ticket_ids,
ticket_count: ticket_count || 0,
assets: assets,
}
end
# GET /api/v1/ticket_stats
def stats

View file

@ -268,6 +268,52 @@ returns
false
end
def self.selectors(selectors, limit = 10)
return if !selectors
query, bind_params = _selectors(selectors)
ticket_count = Ticket.where(query, *bind_params).count
tickets = Ticket.where(query, *bind_params).limit(limit)
[ticket_count, tickets]
end
def self._selectors(selectors)
return if !selectors
query = ''
bind_params = []
selectors.each {|attribute, selector|
if query != ''
query += ' AND '
end
next if !selector
next if !selector.respond_to?(:key?)
next if !selector['operator']
return nil if !selector['value']
return nil if selector['value'].respond_to?(:key?) && selector['value'].empty?
if selector['operator'] == 'is'
query += "#{attribute} IN (?)"
bind_params.push selector['value']
elsif selector['operator'] == 'is not'
query += "#{attribute} NOT IN (?)"
bind_params.push selector['value']
elsif selector['operator'] == 'contains'
query += "#{attribute} LIKE (?)"
value = "%#{selector['value']}%"
bind_params.push value
elsif selector['operator'] == 'contains not'
query += "#{attribute} NOT LIKE (?)"
value = "%#{selector['value']}%"
bind_params.push value
elsif selector['operator'] == 'before'
query += "#{attribute} <= (?)"
bind_params.push selector['value']
else
fail "Invalid operator '#{selector['operator']}' for '#{selector['value'].inspect}'"
end
}
[query, bind_params]
end
private
def check_generate

View file

@ -3,6 +3,7 @@ Zammad::Application.routes.draw do
# tickets
match api_path + '/tickets/search', to: 'tickets#search', via: [:get, :post]
match api_path + '/tickets/selector', to: 'tickets#selector', via: :post
match api_path + '/tickets', to: 'tickets#index', via: :get
match api_path + '/tickets/:id', to: 'tickets#show', via: :get
match api_path + '/tickets', to: 'tickets#create', via: :post