Added preview for ticket selector.
This commit is contained in:
parent
f4b642726e
commit
3fc3ad5e5a
6 changed files with 133 additions and 21 deletions
|
@ -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
|
|
@ -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 = [
|
||||
|
|
|
@ -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>
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue