Init version of user zoom.
This commit is contained in:
parent
acd7d5c52c
commit
c3025f87c3
8 changed files with 457 additions and 111 deletions
|
@ -234,9 +234,8 @@ class App.Controller extends Spine.Controller
|
|||
ticket_id = $(@).data('id')
|
||||
ticket = App.Ticket.fullLocal( ticket_id )
|
||||
ticket.humanTime = ui.humanTime(ticket.created_at)
|
||||
# insert data
|
||||
App.view('popover/ticket')(
|
||||
ticket: ticket,
|
||||
ticket: ticket
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class App.UserZoom extends App.Controller
|
||||
elements:
|
||||
'.tabsSidebar' : 'sidebar'
|
||||
events:
|
||||
'focusout [data-type=update]': 'update',
|
||||
|
||||
constructor: (params) ->
|
||||
super
|
||||
|
@ -12,7 +12,11 @@ class App.UserZoom extends App.Controller
|
|||
|
||||
@navupdate '#'
|
||||
|
||||
App.User.full( @user_id, @render )
|
||||
# subscribe and reload data / fetch new data if triggered
|
||||
@subscribeId = App.User.full( @user_id, @render, false, true )
|
||||
|
||||
release: =>
|
||||
App.User.unsubscribe(@subscribeId)
|
||||
|
||||
meta: =>
|
||||
meta =
|
||||
|
@ -35,10 +39,7 @@ class App.UserZoom extends App.Controller
|
|||
@navupdate '#'
|
||||
|
||||
changed: =>
|
||||
formCurrent = @formParam( @el.find('.ticket-update') )
|
||||
diff = difference( @formDefault, formCurrent )
|
||||
return false if !diff || _.isEmpty( diff )
|
||||
return true
|
||||
false
|
||||
|
||||
render: (user) =>
|
||||
|
||||
|
@ -46,12 +47,43 @@ class App.UserZoom extends App.Controller
|
|||
@doNotLog = 1
|
||||
@recentView( 'User', @user_id )
|
||||
|
||||
# get display data
|
||||
userData = []
|
||||
for item2 in App.User.configure_attributes
|
||||
item = _.clone( item2 )
|
||||
|
||||
# check if value for _id exists
|
||||
itemNameValue = item.name
|
||||
itemNameValueNew = itemNameValue.substr( 0, itemNameValue.length - 3 )
|
||||
if itemNameValueNew of user
|
||||
item.name = itemNameValueNew
|
||||
|
||||
# add to show if value exists
|
||||
if user[item.name] || item.tag is 'textarea'
|
||||
|
||||
# do not show firstname and lastname / already show via diplayName()
|
||||
if item.name isnt 'firstname' && item.name isnt 'lastname' && item.name isnt 'organization'
|
||||
if item.info
|
||||
userData.push item
|
||||
|
||||
@html App.view('user_zoom')(
|
||||
user: user
|
||||
userData: userData
|
||||
)
|
||||
|
||||
new Overviews(
|
||||
el: @el
|
||||
@$('[contenteditable]').ce({
|
||||
mode: 'textonly'
|
||||
multiline: true
|
||||
maxlength: 250
|
||||
})
|
||||
|
||||
#new Overviews(
|
||||
# el: @el
|
||||
# user: user
|
||||
#)
|
||||
|
||||
new TicketStats(
|
||||
el: @$('.js-ticket-stats')
|
||||
user: user
|
||||
)
|
||||
|
||||
|
@ -59,31 +91,190 @@ class App.UserZoom extends App.Controller
|
|||
genericObject: user
|
||||
)
|
||||
|
||||
new App.UpdateHeader(
|
||||
el: @el
|
||||
genericObject: user
|
||||
)
|
||||
|
||||
# start action controller
|
||||
showHistory = =>
|
||||
new App.UserHistory( user_id: user.id )
|
||||
|
||||
editUser = =>
|
||||
new App.ControllerGenericEdit(
|
||||
id: user.id
|
||||
genericObject: 'User'
|
||||
screen: 'edit'
|
||||
pageData:
|
||||
title: 'Users'
|
||||
object: 'User'
|
||||
objects: 'Users'
|
||||
)
|
||||
|
||||
actions = [
|
||||
{
|
||||
name: 'edit'
|
||||
title: 'Edit'
|
||||
callback: editUser
|
||||
}
|
||||
{
|
||||
name: 'history'
|
||||
title: 'History'
|
||||
callback: showHistory
|
||||
}
|
||||
]
|
||||
|
||||
new App.ActionRow(
|
||||
el: @el.find('.action')
|
||||
items: actions
|
||||
)
|
||||
|
||||
new Sidebar(
|
||||
el: @sidebar
|
||||
user: user
|
||||
textModule: @textModule
|
||||
update: (e) =>
|
||||
console.log('update')
|
||||
note = $(e.target).ceg()
|
||||
user = App.User.find( @user_id )
|
||||
if user.note isnt note
|
||||
user.updateAttributes( note: note )
|
||||
@log 'notice', 'update', e, note, user
|
||||
|
||||
|
||||
class TicketStats extends App.Controller
|
||||
events:
|
||||
'click .js-userTab': 'showUserTab'
|
||||
'click .js-orgTab': 'showOrgTab'
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
# subscribe and reload data / fetch new data if triggered
|
||||
@subscribeId = App.User.full( @user.id, @load, false, true )
|
||||
|
||||
release: =>
|
||||
App.User.unsubscribe(@subscribeId)
|
||||
|
||||
load: (user) =>
|
||||
@ajax(
|
||||
id: 'ticket_stats_' + user.id,
|
||||
type: 'GET',
|
||||
url: @apiPath + '/ticket_stats/' + user.id,
|
||||
success: (data) =>
|
||||
# load assets
|
||||
App.Collection.loadAssets( data.assets )
|
||||
|
||||
@render(data)
|
||||
)
|
||||
|
||||
showOrgTab: =>
|
||||
@$('.js-userTab').removeClass('active')
|
||||
@$('.js-orgTab').addClass('active')
|
||||
@$('.js-user').addClass('hide')
|
||||
@$('.js-org').removeClass('hide')
|
||||
|
||||
showUserTab: =>
|
||||
@$('.js-userTab').addClass('active')
|
||||
@$('.js-orgTab').removeClass('active')
|
||||
@$('.js-user').removeClass('hide')
|
||||
@$('.js-org').addClass('hide')
|
||||
|
||||
render: (data) =>
|
||||
|
||||
@html App.view('user_zoom/ticket_stats')(
|
||||
user: @user
|
||||
)
|
||||
|
||||
limit = 5
|
||||
new TicketStatsList(
|
||||
el: @$('.js-user-open-tickets')
|
||||
user: @user
|
||||
head: 'Open Ticket'
|
||||
ticket_ids: data.user_tickets_open_ids
|
||||
limit: limit
|
||||
)
|
||||
new TicketStatsList(
|
||||
el: @$('.js-user-closed-tickets')
|
||||
user: @user
|
||||
head: 'Closed Ticket'
|
||||
ticket_ids: data.user_tickets_closed_ids
|
||||
limit: limit
|
||||
)
|
||||
new TicketStatsFrequency(
|
||||
el: @$('.js-user-frequency')
|
||||
user: @user
|
||||
ticket_volume_by_year: data.user_ticket_volume_by_year
|
||||
)
|
||||
|
||||
new TicketStatsList(
|
||||
el: @$('.js-org-open-tickets')
|
||||
user: @user
|
||||
head: 'Open Ticket'
|
||||
ticket_ids: data.org_tickets_open_ids
|
||||
limit: limit
|
||||
)
|
||||
new TicketStatsList(
|
||||
el: @$('.js-org-closed-tickets')
|
||||
user: @user
|
||||
head: 'Closed Ticket'
|
||||
ticket_ids: data.org_tickets_closed_ids
|
||||
limit: limit
|
||||
)
|
||||
new TicketStatsFrequency(
|
||||
el: @$('.js-org-frequency')
|
||||
user: @user
|
||||
ticket_volume_by_year: data.org_ticket_volume_by_year
|
||||
)
|
||||
|
||||
class TicketStatsList extends App.Controller
|
||||
events:
|
||||
'click .js-showAll': 'showAll'
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
@render()
|
||||
|
||||
render: =>
|
||||
|
||||
ticket_ids_show = []
|
||||
if !@all
|
||||
count = 0
|
||||
for ticket_id in @ticket_ids
|
||||
count += 1
|
||||
if count <= @limit
|
||||
ticket_ids_show.push ticket_id
|
||||
else
|
||||
ticket_ids_show = @ticket_ids
|
||||
|
||||
@html App.view('user_zoom/ticket_stats_list')(
|
||||
user: @user
|
||||
head: @head
|
||||
ticket_ids: @ticket_ids
|
||||
ticket_ids_show: ticket_ids_show
|
||||
limit: @limit
|
||||
)
|
||||
@frontendTimeUpdate()
|
||||
@ticketPopups()
|
||||
|
||||
showAll: (e) =>
|
||||
e.preventDefault()
|
||||
@all = true
|
||||
@render()
|
||||
|
||||
class TicketStatsFrequency extends App.Controller
|
||||
constructor: ->
|
||||
super
|
||||
@render()
|
||||
|
||||
render: (data) =>
|
||||
|
||||
# find 100%
|
||||
max = 0
|
||||
for item in @ticket_volume_by_year
|
||||
if item.closed > max
|
||||
max = item.closed
|
||||
if item.created > max
|
||||
max = item.created
|
||||
console.log('MM', max)
|
||||
for item in @ticket_volume_by_year
|
||||
item.created_in_percent = 100 / max * item.created
|
||||
item.closed_in_percent = 100 / max * item.closed
|
||||
|
||||
@html App.view('user_zoom/ticket_stats_frequency')(
|
||||
user: @user
|
||||
ticket_volume_by_year: @ticket_volume_by_year.reverse()
|
||||
)
|
||||
|
||||
class Overviews extends App.Controller
|
||||
|
@ -154,80 +345,6 @@ class Overviews extends App.Controller
|
|||
@el.find( '#sortable' ).sortable( dndOptions )
|
||||
@el.find( '#sortable-sidebar' ).sortable( dndOptions )
|
||||
|
||||
class Sidebar extends App.Controller
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
# render ui
|
||||
@render()
|
||||
|
||||
render: ->
|
||||
|
||||
items = []
|
||||
|
||||
showCustomer = (el) =>
|
||||
new App.WidgetUser(
|
||||
el: el
|
||||
user_id: @user.id
|
||||
)
|
||||
|
||||
editCustomer = (e, el) =>
|
||||
new App.ControllerGenericEdit(
|
||||
id: @user.id
|
||||
genericObject: 'User'
|
||||
screen: 'edit'
|
||||
pageData:
|
||||
title: 'Users'
|
||||
object: 'User'
|
||||
objects: 'Users'
|
||||
)
|
||||
items.push {
|
||||
head: 'Customer'
|
||||
name: 'customer'
|
||||
icon: 'person'
|
||||
actions: [
|
||||
{
|
||||
name: 'Edit Customer'
|
||||
class: 'glyphicon glyphicon-edit'
|
||||
callback: editCustomer
|
||||
},
|
||||
]
|
||||
callback: showCustomer
|
||||
}
|
||||
|
||||
if @user.organization_id
|
||||
editOrganization = (e, el) =>
|
||||
new App.ControllerGenericEdit(
|
||||
id: @user.organization_id
|
||||
genericObject: 'Organization'
|
||||
pageData:
|
||||
title: 'Organizations'
|
||||
object: 'Organization'
|
||||
objects: 'Organizations'
|
||||
)
|
||||
showOrganization = (el) =>
|
||||
new App.WidgetOrganization(
|
||||
el: el
|
||||
organization_id: @user.organization_id
|
||||
)
|
||||
items.push {
|
||||
head: 'Organization'
|
||||
name: 'organization'
|
||||
icon: 'group'
|
||||
actions: [
|
||||
{
|
||||
name: 'Edit Organization'
|
||||
class: 'glyphicon glyphicon-edit'
|
||||
callback: editOrganization
|
||||
},
|
||||
]
|
||||
callback: showOrganization
|
||||
}
|
||||
|
||||
new App.Sidebar(
|
||||
el: @el
|
||||
items: items
|
||||
)
|
||||
|
||||
class Router extends App.ControllerPermanent
|
||||
constructor: (params) ->
|
||||
|
|
|
@ -1,18 +1,40 @@
|
|||
<div class="tabsSidebar-holder flex vertical">
|
||||
<div class="flex u-positionOrigin horizontal">
|
||||
<div class="main flex tabsSidebar-sidebarSpacer tabsSidebar-tabsSpacer">
|
||||
<div class="userZoom">
|
||||
<div class="page-header">
|
||||
<h1><%- @T( @head ) %></h1>
|
||||
<div class="flex userZoom">
|
||||
|
||||
<div class="userZoom-window">
|
||||
<div class="userZoom-section vertical centered">
|
||||
<div class="align-right userZoom-action dropdown dropdown--actions action"></div>
|
||||
<%- @user.avatar("80") %>
|
||||
<h1><%= @user.displayName() %></h1>
|
||||
<% if @user.organization: %>
|
||||
<div class="userZoom-organisation"><a href="<%- @user.organization.uiUrl() %>"><%= @user.organization.displayName() %></a></div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="main-overviews" id="sortable"></div>
|
||||
<div class="userZoom-section">
|
||||
<div class="userZoom-details horizontal wrap">
|
||||
<% for row in @userData: %>
|
||||
<% if @user[row.name]: %>
|
||||
<% if row.tag isnt 'textarea': %>
|
||||
<div class="userZoom-detailsEntry">
|
||||
<label><%- @Ti( row.display ) %></label>
|
||||
<%- @L( @P( @user[row.name] ) ) %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% for row in @userData: %>
|
||||
<% if row.tag is 'textarea': %>
|
||||
<div class="userZoom-detailsEntry" style="width: 100%;">
|
||||
<label><%- @Ti( row.display ) %></label>
|
||||
<div contenteditable="true" data-name="<%= row.name %>" data-type="update" data-placeholder="<%- @T('Add a Note') %>"><%= @user[row.name] %></div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tabsSidebar vertical"></div>
|
||||
<div class="userZoom-section js-ticket-stats"></div>
|
||||
|
||||
</div>
|
||||
<form class="bottom-form form-inline horizontal" role="form">
|
||||
<div class="action"></div>
|
||||
</form>
|
||||
|
||||
</div>
|
|
@ -0,0 +1,24 @@
|
|||
<% if @user && @user.organization: %>
|
||||
<div class="tabs wide-tabs horizontal">
|
||||
<div class="tab js-userTab active"><%- @T('Tickets of User') %></div>
|
||||
<div class="tab js-orgTab"><%- @T('Tickets of Organization') %></div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="js-user">
|
||||
<div class="userZoom-ticketLists horizontal">
|
||||
<div class="userZoom-ticketList js-user-open-tickets"></div>
|
||||
<div class="userZoom-ticketList js-user-closed-tickets"></div>
|
||||
</div>
|
||||
|
||||
<div class="frequency stat-widget vertical js-user-frequency"></div>
|
||||
</div>
|
||||
|
||||
<div class="js-org hide">
|
||||
<div class="userZoom-ticketLists horizontal">
|
||||
<div class="userZoom-ticketList js-org-open-tickets"></div>
|
||||
<div class="userZoom-ticketList js-org-closed-tickets"></div>
|
||||
</div>
|
||||
|
||||
<div class="frequency stat-widget vertical js-org-frequency"></div>
|
||||
</div>
|
|
@ -0,0 +1,16 @@
|
|||
<h3>Frequency</h3>
|
||||
<div class="stat-graphic">
|
||||
<% for item in @ticket_volume_by_year: %>
|
||||
<div class="stats-row">
|
||||
<div class="stat-bars">
|
||||
<div class="stat-bar primary" style="height: <%- item.closed_in_percent %>%"></div>
|
||||
<div class="stat-bar secondary" style="height: <%- item.created_in_percent %>%"></div>
|
||||
</div>
|
||||
<div class="stat-label"><%- @T(item.text.substr(0,3)) %></div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="stat-legend">
|
||||
<div class="stat-legendEntry primary"><span class="primary stat-circle"></span><%- @T('Closed') %></div>
|
||||
<div class="stat-legendEntry secondary"><span class="secondary stat-circle"></span><%- @T('Created') %></div>
|
||||
</div>
|
|
@ -0,0 +1,18 @@
|
|||
<label><%- @T(@head) %> (<%= @ticket_ids.length %>)</label>
|
||||
<ol class="tasks tasks--standalone">
|
||||
<% for ticket_id in @ticket_ids_show: %>
|
||||
<% ticket = App.Ticket.fullLocal(ticket_id) %>
|
||||
<li class="task">
|
||||
<div class="icon-holder">
|
||||
<div class="icon <%- ticket.icon() %>"></div>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<a class="name ticket-popover" data-id="<%- ticket_id %>" href="<%- ticket.uiUrl() %>"><%= ticket.title %></a>
|
||||
<div class="time humanTimeFromNow" data-time="<%- ticket.created_at %>"></div>
|
||||
</div>
|
||||
</li>
|
||||
<% end %>
|
||||
</ol>
|
||||
<% if @ticket_ids.length > @ticket_ids_show.length: %>
|
||||
<a href="#" class="js-showAll"><%- @T('Show all ...') %></a>
|
||||
<% end %>
|
|
@ -365,10 +365,159 @@ class TicketsController < ApplicationController
|
|||
}
|
||||
end
|
||||
|
||||
# GET /api/v1/ticket_stats/1
|
||||
def stats
|
||||
user = User.find(params[:id])
|
||||
|
||||
# permissin check
|
||||
#return if !ticket_permission(ticket)
|
||||
|
||||
# lookup open user tickets
|
||||
limit = 100
|
||||
assets = {}
|
||||
condition = {
|
||||
'tickets.state_id' => Ticket::State.by_category('open'),
|
||||
'tickets.customer_id' => user.id,
|
||||
}
|
||||
user_tickets_open = Ticket.search(
|
||||
:limit => limit,
|
||||
#:query => params[:term],
|
||||
:condition => condition,
|
||||
:current_user => current_user,
|
||||
:detail => true,
|
||||
)
|
||||
user_tickets_open_ids = assets_of_tickets(user_tickets_open, assets)
|
||||
|
||||
# lookup closed user tickets
|
||||
condition = {
|
||||
'tickets.state_id' => Ticket::State.by_category('closed'),
|
||||
'tickets.customer_id' => user.id,
|
||||
}
|
||||
user_tickets_closed = Ticket.search(
|
||||
:limit => limit,
|
||||
#:query => params[:term],
|
||||
:condition => condition,
|
||||
:current_user => current_user,
|
||||
:detail => true,
|
||||
)
|
||||
user_tickets_closed_ids = assets_of_tickets(user_tickets_closed, assets)
|
||||
|
||||
|
||||
# lookup open org tickets
|
||||
org_tickets_open_ids = []
|
||||
if user.organization_id
|
||||
condition = {
|
||||
'tickets.state_id' => Ticket::State.by_category('open'),
|
||||
'tickets.organization_id' => user.organization_id,
|
||||
}
|
||||
org_tickets_open = Ticket.search(
|
||||
:limit => limit,
|
||||
#:query => params[:term],
|
||||
:condition => condition,
|
||||
:current_user => current_user,
|
||||
:detail => true,
|
||||
)
|
||||
org_tickets_open_ids = assets_of_tickets(org_tickets_open, assets)
|
||||
end
|
||||
|
||||
# lookup closed org tickets
|
||||
org_tickets_closed_ids = []
|
||||
if user.organization_id
|
||||
condition = {
|
||||
'tickets.state_id' => Ticket::State.by_category('closed'),
|
||||
'tickets.organization_id' => user.organization_id,
|
||||
}
|
||||
org_tickets_closed = Ticket.search(
|
||||
:limit => limit,
|
||||
#:query => params[:term],
|
||||
:condition => condition,
|
||||
:current_user => current_user,
|
||||
:detail => true,
|
||||
)
|
||||
org_tickets_closed_ids = assets_of_tickets(org_tickets_closed, assets)
|
||||
end
|
||||
|
||||
# generate stats by user
|
||||
user_ticket_volume_by_year = []
|
||||
now = DateTime.now
|
||||
(0..11).each {|month_back|
|
||||
date_to_check = DateTime.now - month_back.month
|
||||
date_start = "#{date_to_check.year}-#{date_to_check.month}-#{01} 00:00:00"
|
||||
date_end = "#{date_to_check.year}-#{date_to_check.month}-#{date_to_check.end_of_month.day} 00:00:00"
|
||||
|
||||
condition = {
|
||||
'tickets.customer_id' => user.id,
|
||||
}
|
||||
|
||||
# created
|
||||
created = Ticket.where('created_at > ? AND created_at < ?', date_start, date_end ).where(condition).count
|
||||
|
||||
# closed
|
||||
closed = Ticket.where('close_time > ? AND close_time < ?', date_start, date_end ).where(condition).count
|
||||
|
||||
data = {
|
||||
:month => date_to_check.month,
|
||||
:year => date_to_check.year,
|
||||
:text => Date::MONTHNAMES[date_to_check.month],
|
||||
:created => created,
|
||||
:closed => closed,
|
||||
}
|
||||
user_ticket_volume_by_year.push data
|
||||
}
|
||||
|
||||
# generate stats by org
|
||||
org_ticket_volume_by_year = []
|
||||
now = DateTime.now
|
||||
(0..11).each {|month_back|
|
||||
date_to_check = DateTime.now - month_back.month
|
||||
date_start = "#{date_to_check.year}-#{date_to_check.month}-#{01} 00:00:00"
|
||||
date_end = "#{date_to_check.year}-#{date_to_check.month}-#{date_to_check.end_of_month.day} 00:00:00"
|
||||
|
||||
condition = {
|
||||
'tickets.organization_id' => user.organization_id,
|
||||
}
|
||||
|
||||
# created
|
||||
created = Ticket.where('created_at > ? AND created_at < ?', date_start, date_end ).where(condition).count
|
||||
|
||||
# closed
|
||||
closed = Ticket.where('close_time > ? AND close_time < ?', date_start, date_end ).where(condition).count
|
||||
|
||||
data = {
|
||||
:month => date_to_check.month,
|
||||
:year => date_to_check.year,
|
||||
:text => Date::MONTHNAMES[date_to_check.month],
|
||||
:created => created,
|
||||
:closed => closed,
|
||||
}
|
||||
org_ticket_volume_by_year.push data
|
||||
}
|
||||
|
||||
# return result
|
||||
render :json => {
|
||||
:user_tickets_open_ids => user_tickets_open_ids,
|
||||
:user_tickets_closed_ids => user_tickets_closed_ids,
|
||||
:org_tickets_open_ids => org_tickets_open_ids,
|
||||
:org_tickets_closed_ids => org_tickets_closed_ids,
|
||||
:user_ticket_volume_by_year => user_ticket_volume_by_year,
|
||||
:org_ticket_volume_by_year => org_ticket_volume_by_year,
|
||||
:assets => assets,
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def assets_of_tickets(tickets, assets)
|
||||
ticket_ids = []
|
||||
tickets.each do |ticket|
|
||||
ticket_ids.push ticket.id
|
||||
assets = ticket.assets(assets)
|
||||
end
|
||||
return ticket_ids
|
||||
end
|
||||
|
||||
def article_create(ticket, params)
|
||||
puts params.inspect
|
||||
|
||||
# create article if given
|
||||
form_id = params[:form_id]
|
||||
params.delete(:form_id)
|
||||
|
|
|
@ -13,6 +13,7 @@ Zammad::Application.routes.draw do
|
|||
match api_path + '/ticket_customer', :to => 'tickets#ticket_customer', :via => :get
|
||||
match api_path + '/ticket_related/:ticket_id', :to => 'tickets#ticket_related', :via => :get
|
||||
match api_path + '/ticket_merge/:slave_ticket_id/:master_ticket_number', :to => 'tickets#ticket_merge', :via => :get
|
||||
match api_path + '/ticket_stats/:id', :to => 'tickets#stats', :via => :get
|
||||
|
||||
# ticket overviews
|
||||
match api_path + '/ticket_overviews', :to => 'ticket_overviews#show', :via => :get
|
||||
|
|
Loading…
Reference in a new issue