Added first steps test ticket feature.

This commit is contained in:
Martin Edenhofer 2016-03-01 00:52:51 +01:00
parent 77d4f00957
commit 6f5c0d6004
12 changed files with 284 additions and 87 deletions

View file

@ -637,6 +637,7 @@ class App.ControllerModal extends App.Controller
buttonSubmit: true
headPrefix: ''
shown: true
closeOnAnyClick: false
events:
'submit form': 'submit'
@ -724,6 +725,11 @@ class App.ControllerModal extends App.Controller
@onClosed()
$('.modal').remove()
if @closeOnAnyClick
@el.on('click', =>
@close()
)
close: (e) =>
if e
e.preventDefault()

View file

@ -1,19 +1,23 @@
class App.DashboardFirstSteps extends App.Controller
events:
'click a': 'scrollIntoView'
'click .js-testTicket': 'testTicket'
'click .js-inviteAgent': 'inviteAgent'
'click .js-inviteCustomer': 'inviteCustomer'
constructor: ->
super
@load()
@interval(@load, 35000)
load: =>
return if @lastData && !@el.is(':visible')
@ajax(
id: 'first_steps'
type: 'GET'
url: @apiPath + '/first_steps'
success: (data) =>
return if _.isEqual(@lastData, data)
@lastData = data
@render(data)
)
@ -31,20 +35,63 @@ class App.DashboardFirstSteps extends App.Controller
@scrollToIfNeeded(element)
@delay(delay, 40)
inviteAgent: (e) =>
inviteAgent: (e) ->
e.preventDefault()
new App.InviteUser(
container: @el.closest('.content')
#container: @el.closest('.content')
head: 'Invite Colleagues'
screen: 'invite_agent'
role: 'Agent'
)
inviteCustomer: (e) =>
inviteCustomer: (e) ->
e.preventDefault()
new App.InviteUser(
container: @el.closest('.content')
#container: @el.closest('.content')
head: 'Invite Customer'
screen: 'invite_customer'
role: 'Customer'
)
testTicketLoading: =>
template = App.view('dashboard/first_steps_test_ticket_loading')()
create = =>
@ajax(
id: 'test_ticket'
type: 'POST'
url: @apiPath + '/first_steps/test_ticket'
processData: true
success: (data) =>
App.Collection.loadAssets(data.assets)
ticket = App.Ticket.fullLocal(data.ticket_id)
overview = App.Overview.fullLocal(data.overview_id)
finish = @testTicketFinish(
overviewName: App.i18n.translatePlain(overview.name)
overviewUrl: overview.uiUrl()
ticketUrl: ticket.uiUrl()
ticketNumber: ticket.number
)
$('.modal .modal-body').html(finish)
)
@delay(create, 1800)
template
testTicketFinish: (data) ->
App.view('dashboard/first_steps_test_ticket_finish')(data)
testTicket: (e) =>
e.preventDefault()
modal = new App.ControllerModal(
head: 'Test Ticket'
#container: @el.parents('.content')
content: @testTicketLoading
shown: true
buttonSubmit: false
buttonCancel: false
small: true
closeOnAnyClick: true
onSubmit: ->
modal.close()
)

View file

@ -227,15 +227,19 @@ class _i18nSingleton extends Spine.Module
.replace(/\/\/(.+?)\/\//gm, '<del>$1</del>')
.replace(/§(.+?)§/gm, '<kbd>$1</kbd>')
# search %s
# search %s|%l
if args
for arg in args
translated = translated.replace(/%(s|l)/, (match) ->
if match is '%s'
if quote
argNew = App.Utils.htmlEscape(arg)
else
argNew = arg
translated = translated.replace(/%s/, argNew)
argNew
else
"<a href=\"#{arg}\">🔗</a>"
)
@log 'debug', 'translate', string, args, translated

View file

@ -149,3 +149,6 @@ class App.Overview extends App.Model
Sie können auch individuelle Übersichten für einzelne Agenten oder agenten Gruppen erstellen.
'''
uiUrl: ->
'#ticket/view/' + @link

View file

@ -0,0 +1,2 @@
<p><%- @T('A Test Ticket has been created, you can find it in your overview |"%s"|', @overviewName) %></p>
<p><%- @T('To open and work on it, click on the Ticket |#%s| directly %l or in the overview |"%s"| %l and click on the Ticket.', @ticketNumber, @ticketUrl, @overviewName, @overviewUrl) %></p>

View file

@ -0,0 +1,5 @@
<div class="wizard-body vertical justified">
<p class="wizard-loadingText">
<span class="loading icon"></span>
</p>
</div>

View file

@ -4,11 +4,7 @@ class FirstStepsController < ApplicationController
before_action :authentication_check
def index
result = []
if !current_user.role?(%w(Agent Admin))
render json: result
return
end
return if !access?
invite_agents = false
#if User.of_role('Agent').count > 2
@ -89,7 +85,8 @@ class FirstStepsController < ApplicationController
{
name: 'Create a Test Ticket',
checked: false,
location: '#create_test_ticket',
location: '#',
class: 'js-testTicket',
},
{
name: 'Create Overviews',
@ -135,6 +132,8 @@ class FirstStepsController < ApplicationController
},
]
check_availability(result)
render json: result
return
end
@ -151,7 +150,8 @@ class FirstStepsController < ApplicationController
{
name: 'Create a Test Ticket',
checked: false,
location: '#create_test_ticket',
location: '#',
class: 'js-testTicket',
},
{
name: 'Invite Customers to create issues in Zammad',
@ -163,7 +163,98 @@ class FirstStepsController < ApplicationController
},
]
check_availability(result)
render json: result
end
def test_ticket
return if !access?
agent = current_user
customer = test_customer
from = "#{customer.fullname} <#{customer.email}>"
original_user_id = UserInfo.current_user_id
result = NotificationFactory.template(
template: 'test_ticket',
locale: agent.preferences[:locale] || 'en-us',
objects: {
agent: agent,
customer: customer,
},
raw: true,
)
UserInfo.current_user_id = customer.id
ticket = Ticket.create(
group_id: Group.find_by(active: true).id,
customer_id: customer.id,
owner_id: User.find_by(login: '-').id,
title: result[:subject],
state_id: Ticket::State.find_by(name: 'new').id,
priority_id: Ticket::Priority.find_by(name: '2 normal').id,
)
article = Ticket::Article.create(
ticket_id: ticket.id,
type_id: Ticket::Article::Type.find_by(name: 'phone').id,
sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id,
from: from,
body: result[:body],
content_type: 'text/html',
internal: false,
)
UserInfo.current_user_id = original_user_id
overview = test_overview
assets = ticket.assets({})
assets = article.assets(assets)
assets = overview.assets(assets)
render json: {
overview_id: overview.id,
ticket_id: ticket.id,
assets: assets,
}
end
private
def test_overview
Overview.find_by(name: 'Unassigned & Open')
end
def test_customer
User.find_by(login: 'nicole.braun@zammad.org')
end
def access?
return true if current_user.role?(%w(Agent Admin))
render json: []
false
end
def check_availability(result)
test_ticket_active = true
overview = test_overview
if !overview
test_ticket_active = false
elsif overview.updated_by_id != 1
test_ticket_active = false
end
if !test_customer
test_ticket_active = false
end
if Group.where(active: true).count > 1
test_ticket_active = false
end
return result if test_ticket_active
result.each {|item|
items = []
item[:items].each {|local_item|
next if local_item[:name] == 'Create a Test Ticket'
items.push local_item
}
item[:items] = items
}
result
end
end

View file

@ -0,0 +1,9 @@
Test Ticket!
<p>Hallo <%= d 'agent.firstname' %>,</p>
<br>
<p>dies ist ein <b>Test Ticket</b>. Ich bin ein Kunde und benötige Hilfe! :)</p>
<br>
<p><%= d 'customer.fullname' %></p>
<br>
<p>Das Zammad Projekt</p>

View file

@ -0,0 +1,9 @@
Test Ticket!
<p>Dear <%= d 'agent.firstname' %>,</p>
<br>
<p>this is a <b>Test Ticket</b>. I'm a customer and I need some help! :)</p>
<br>
<p><%= d 'customer.fullname' %></p>
<br>
<p>The Zammad Project</p>

View file

@ -2,5 +2,6 @@ Zammad::Application.routes.draw do
api_path = Rails.configuration.api_path
match api_path + '/first_steps', to: 'first_steps#index', via: :get
match api_path + '/first_steps/test_ticket', to: 'first_steps#test_ticket', via: :post
end

View file

@ -1589,7 +1589,7 @@ user = User.create_if_not_exists(
)
UserInfo.current_user_id = 1
roles = Role.where( name: 'Customer' )
roles = Role.find_by(name: 'Customer')
organizations = Organization.all
groups = Group.all
org_community = Organization.create_if_not_exists(
@ -1608,48 +1608,48 @@ user_community = User.create_or_update(
organization_id: org_community.id,
)
Link::Type.create_if_not_exists( id: 1, name: 'normal' )
Link::Object.create_if_not_exists( id: 1, name: 'Ticket' )
Link::Object.create_if_not_exists( id: 2, name: 'Announcement' )
Link::Object.create_if_not_exists( id: 3, name: 'Question/Answer' )
Link::Object.create_if_not_exists( id: 4, name: 'Idea' )
Link::Object.create_if_not_exists( id: 5, name: 'Bug' )
Link::Type.create_if_not_exists(id: 1, name: 'normal')
Link::Object.create_if_not_exists(id: 1, name: 'Ticket')
Link::Object.create_if_not_exists(id: 2, name: 'Announcement')
Link::Object.create_if_not_exists(id: 3, name: 'Question/Answer')
Link::Object.create_if_not_exists(id: 4, name: 'Idea')
Link::Object.create_if_not_exists(id: 5, name: 'Bug')
Ticket::StateType.create_if_not_exists( id: 1, name: 'new' )
Ticket::StateType.create_if_not_exists( id: 2, name: 'open' )
Ticket::StateType.create_if_not_exists( id: 3, name: 'pending reminder' )
Ticket::StateType.create_if_not_exists( id: 4, name: 'pending action' )
Ticket::StateType.create_if_not_exists( id: 5, name: 'closed' )
Ticket::StateType.create_if_not_exists( id: 6, name: 'merged' )
Ticket::StateType.create_if_not_exists( id: 7, name: 'removed' )
Ticket::StateType.create_if_not_exists(id: 1, name: 'new' )
Ticket::StateType.create_if_not_exists(id: 2, name: 'open' )
Ticket::StateType.create_if_not_exists(id: 3, name: 'pending reminder')
Ticket::StateType.create_if_not_exists(id: 4, name: 'pending action')
Ticket::StateType.create_if_not_exists(id: 5, name: 'closed')
Ticket::StateType.create_if_not_exists(id: 6, name: 'merged')
Ticket::StateType.create_if_not_exists(id: 7, name: 'removed')
Ticket::State.create_if_not_exists( id: 1, name: 'new', state_type_id: Ticket::StateType.find_by(name: 'new').id, )
Ticket::State.create_if_not_exists( id: 2, name: 'open', state_type_id: Ticket::StateType.find_by(name: 'open').id )
Ticket::State.create_if_not_exists( id: 3, name: 'pending reminder', state_type_id: Ticket::StateType.find_by(name: 'pending reminder').id, ignore_escalation: true )
Ticket::State.create_if_not_exists( id: 4, name: 'closed', state_type_id: Ticket::StateType.find_by(name: 'closed').id, ignore_escalation: true )
Ticket::State.create_if_not_exists( id: 5, name: 'merged', state_type_id: Ticket::StateType.find_by(name: 'merged').id, ignore_escalation: true )
Ticket::State.create_if_not_exists( id: 6, name: 'removed', state_type_id: Ticket::StateType.find_by(name: 'removed').id, active: false, ignore_escalation: true )
Ticket::State.create_if_not_exists( id: 7, name: 'pending close', state_type_id: Ticket::StateType.find_by(name: 'pending action').id, next_state_id: 4, ignore_escalation: true )
Ticket::State.create_if_not_exists(id: 1, name: 'new', state_type_id: Ticket::StateType.find_by(name: 'new').id, )
Ticket::State.create_if_not_exists(id: 2, name: 'open', state_type_id: Ticket::StateType.find_by(name: 'open').id)
Ticket::State.create_if_not_exists(id: 3, name: 'pending reminder', state_type_id: Ticket::StateType.find_by(name: 'pending reminder').id, ignore_escalation: true)
Ticket::State.create_if_not_exists(id: 4, name: 'closed', state_type_id: Ticket::StateType.find_by(name: 'closed').id, ignore_escalation: true)
Ticket::State.create_if_not_exists(id: 5, name: 'merged', state_type_id: Ticket::StateType.find_by(name: 'merged').id, ignore_escalation: true)
Ticket::State.create_if_not_exists(id: 6, name: 'removed', state_type_id: Ticket::StateType.find_by(name: 'removed').id, active: false, ignore_escalation: true)
Ticket::State.create_if_not_exists(id: 7, name: 'pending close', state_type_id: Ticket::StateType.find_by(name: 'pending action').id, next_state_id: 4, ignore_escalation: true)
Ticket::Priority.create_if_not_exists( id: 1, name: '1 low' )
Ticket::Priority.create_if_not_exists( id: 2, name: '2 normal' )
Ticket::Priority.create_if_not_exists( id: 3, name: '3 high' )
Ticket::Priority.create_if_not_exists(id: 1, name: '1 low')
Ticket::Priority.create_if_not_exists(id: 2, name: '2 normal')
Ticket::Priority.create_if_not_exists(id: 3, name: '3 high')
Ticket::Article::Type.create_if_not_exists( id: 1, name: 'email', communication: true )
Ticket::Article::Type.create_if_not_exists( id: 2, name: 'sms', communication: true )
Ticket::Article::Type.create_if_not_exists( id: 3, name: 'chat', communication: true )
Ticket::Article::Type.create_if_not_exists( id: 4, name: 'fax', communication: true )
Ticket::Article::Type.create_if_not_exists( id: 5, name: 'phone', communication: true )
Ticket::Article::Type.create_if_not_exists( id: 6, name: 'twitter status', communication: true )
Ticket::Article::Type.create_if_not_exists( id: 7, name: 'twitter direct-message', communication: true )
Ticket::Article::Type.create_if_not_exists( id: 8, name: 'facebook feed post', communication: true )
Ticket::Article::Type.create_if_not_exists( id: 9, name: 'facebook feed comment', communication: true )
Ticket::Article::Type.create_if_not_exists( id: 10, name: 'note', communication: false )
Ticket::Article::Type.create_if_not_exists( id: 11, name: 'web', communication: true )
Ticket::Article::Type.create_if_not_exists(id: 1, name: 'email', communication: true)
Ticket::Article::Type.create_if_not_exists(id: 2, name: 'sms', communication: true)
Ticket::Article::Type.create_if_not_exists(id: 3, name: 'chat', communication: true)
Ticket::Article::Type.create_if_not_exists(id: 4, name: 'fax', communication: true)
Ticket::Article::Type.create_if_not_exists(id: 5, name: 'phone', communication: true)
Ticket::Article::Type.create_if_not_exists(id: 6, name: 'twitter status', communication: true)
Ticket::Article::Type.create_if_not_exists(id: 7, name: 'twitter direct-message', communication: true)
Ticket::Article::Type.create_if_not_exists(id: 8, name: 'facebook feed post', communication: true)
Ticket::Article::Type.create_if_not_exists(id: 9, name: 'facebook feed comment', communication: true)
Ticket::Article::Type.create_if_not_exists(id: 10, name: 'note', communication: false)
Ticket::Article::Type.create_if_not_exists(id: 11, name: 'web', communication: true)
Ticket::Article::Sender.create_if_not_exists( id: 1, name: 'Agent' )
Ticket::Article::Sender.create_if_not_exists( id: 2, name: 'Customer' )
Ticket::Article::Sender.create_if_not_exists( id: 3, name: 'System' )
Ticket::Article::Sender.create_if_not_exists(id: 1, name: 'Agent')
Ticket::Article::Sender.create_if_not_exists(id: 2, name: 'Customer')
Ticket::Article::Sender.create_if_not_exists(id: 3, name: 'System')
Macro.create_if_not_exists(
name: 'Close & Tag as Spam',
@ -1668,21 +1668,21 @@ Macro.create_if_not_exists(
UserInfo.current_user_id = user_community.id
ticket = Ticket.create(
group_id: Group.where( name: 'Users' ).first.id,
customer_id: User.where( login: 'nicole.braun@zammad.org' ).first.id,
owner_id: User.where( login: '-' ).first.id,
group_id: Group.find_by(name: 'Users').id,
customer_id: User.find_by(login: 'nicole.braun@zammad.org').id,
owner_id: User.find_by(login: '-').id,
title: 'Welcome to Zammad!',
state_id: Ticket::State.where( name: 'new' ).first.id,
priority_id: Ticket::Priority.where( name: '2 normal' ).first.id,
state_id: Ticket::State.find_by(name: 'new').id,
priority_id: Ticket::Priority.find_by(name: '2 normal').id,
)
Ticket::Article.create(
ticket_id: ticket.id,
type_id: Ticket::Article::Type.where(name: 'phone' ).first.id,
sender_id: Ticket::Article::Sender.where(name: 'Customer' ).first.id,
type_id: Ticket::Article::Type.find_by(name: 'phone').id,
sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id,
from: 'Zammad Feedback <feedback@zammad.org>',
body: 'Welcome!
Thank you for installing Zammad.
Thank you for choosing Zammad.
You will find updates and patches at http://zammad.org/. Online
documentation is available at http://guides.zammad.org/. You can also
@ -1690,13 +1690,13 @@ use our forums at http://forums.zammad.org/
Regards,
The Zammad.org Project
The Zammad Project
',
internal: false,
)
UserInfo.current_user_id = 1
overview_role = Role.where( name: 'Agent' ).first
overview_role = Role.find_by(name: 'Agent')
Overview.create_if_not_exists(
name: 'My assigned Tickets',
link: 'my_assigned',
@ -1858,7 +1858,7 @@ Overview.create_if_not_exists(
},
)
overview_role = Role.where( name: 'Customer' ).first
overview_role = Role.find_by(name: 'Customer')
Overview.create_if_not_exists(
name: 'My Tickets',
link: 'my_tickets',
@ -1994,8 +1994,8 @@ Network::Category.create_if_not_exists(
id: 1,
name: 'Announcements',
network_id: network.id,
network_category_type_id: Network::Category::Type.where(name: 'Announcement').first.id,
network_privacy_id: Network::Privacy.where(name: 'logged in and moderator').first.id,
network_category_type_id: Network::Category::Type.find_by(name: 'Announcement').id,
network_privacy_id: Network::Privacy.find_by(name: 'logged in and moderator').id,
allow_comments: true,
)
Network::Category.create_if_not_exists(
@ -2003,30 +2003,30 @@ Network::Category.create_if_not_exists(
name: 'Questions',
network_id: network.id,
allow_comments: true,
network_category_type_id: Network::Category::Type.where(name: 'Question').first.id,
network_privacy_id: Network::Privacy.where(name: 'logged in').first.id,
# :network_categories_moderator_user_ids => User.where(:login => '-').first.id,
network_category_type_id: Network::Category::Type.find_by(name: 'Question').id,
network_privacy_id: Network::Privacy.find_by(name: 'logged in').id,
# network_categories_moderator_user_ids: User.find_by(:login => '-').id,
)
Network::Category.create_if_not_exists(
id: 3,
name: 'Ideas',
network_id: network.id,
network_category_type_id: Network::Category::Type.where(name: 'Idea').first.id,
network_privacy_id: Network::Privacy.where(name: 'logged in').first.id,
network_category_type_id: Network::Category::Type.find_by(name: 'Idea').id,
network_privacy_id: Network::Privacy.find_by(name: 'logged in').id,
allow_comments: true,
)
Network::Category.create_if_not_exists(
id: 4,
name: 'Bug Reports',
network_id: network.id,
network_category_type_id: Network::Category::Type.where(name: 'Bug Report').first.id,
network_privacy_id: Network::Privacy.where(name: 'logged in').first.id,
network_category_type_id: Network::Category::Type.find_by(name: 'Bug Report').id,
network_privacy_id: Network::Privacy.find_by(name: 'logged in').id,
allow_comments: true,
)
item = Network::Item.create(
title: 'Example Announcement',
body: 'Some announcement....',
network_category_id: Network::Category.where(name: 'Announcements').first.id,
network_category_id: Network::Category.find_by(name: 'Announcements').id,
)
Network::Item::Comment.create(
network_item_id: item.id,
@ -2035,7 +2035,7 @@ Network::Item::Comment.create(
item = Network::Item.create(
title: 'Example Question?',
body: 'Some questions....',
network_category_id: Network::Category.where(name: 'Questions').first.id,
network_category_id: Network::Category.find_by(name: 'Questions').id,
)
Network::Item::Comment.create(
network_item_id: item.id,
@ -2044,7 +2044,7 @@ Network::Item::Comment.create(
item = Network::Item.create(
title: 'Example Idea',
body: 'Some idea....',
network_category_id: Network::Category.where(name: 'Ideas').first.id,
network_category_id: Network::Category.find_by(name: 'Ideas').id,
)
Network::Item::Comment.create(
network_item_id: item.id,
@ -2053,7 +2053,7 @@ Network::Item::Comment.create(
item = Network::Item.create(
title: 'Example Bug Report',
body: 'Some bug....',
network_category_id: Network::Category.where(name: 'Bug Reports').first.id,
network_category_id: Network::Category.find_by(name: 'Bug Reports').id,
)
Network::Item::Comment.create(
network_item_id: item.id,

View file

@ -284,6 +284,24 @@ retunes
},
)
only raw subject/body
result = NotificationFactory.template(
template: 'password_reset',
locale: 'en-us',
objects: {
recipient: User.find(2),
},
raw: true,
)
returns
{
subject: 'some sobject',
body: 'some body',
}
=end
def self.template(data)
@ -320,12 +338,14 @@ retunes
message_subject = NotificationFactory::Template.new(data[:objects], data[:locale], template_subject, false).render
message_body = NotificationFactory::Template.new(data[:objects], data[:locale], template_body).render
if !data[:raw]
application_template = nil
File.open('app/views/mailer/application.html.erb', 'r:UTF-8') do |file|
application_template = file.read
end
data[:objects][:message] = message_body
message_body = NotificationFactory::Template.new(data[:objects], data[:locale], application_template).render
end
{
subject: message_subject,
body: message_body,