Fixes #257 - Define default "stay on tab" / "close tab" behavior.
This commit is contained in:
parent
b3bfe71ab8
commit
41691e9846
8 changed files with 224 additions and 5 deletions
|
@ -978,8 +978,14 @@ class App.TicketZoom extends App.Controller
|
|||
@openTicketInOverview(nextTicket)
|
||||
App.Event.trigger('overview:fetch')
|
||||
return
|
||||
|
||||
if taskAction is 'closeTab' || taskAction is 'next_task'
|
||||
else if taskAction is 'closeTabOnTicketClose' || taskAction is 'next_task_on_close'
|
||||
state_type_id = App.TicketState.find(ticket.state_id).state_type_id
|
||||
state_type = App.TicketStateType.find(state_type_id).name
|
||||
if state_type is 'closed'
|
||||
App.Event.trigger('overview:fetch')
|
||||
@taskCloseTicket(true)
|
||||
return
|
||||
else if taskAction is 'closeTab' || taskAction is 'next_task'
|
||||
App.Event.trigger('overview:fetch')
|
||||
@taskCloseTicket(true)
|
||||
return
|
||||
|
|
|
@ -15,7 +15,7 @@ class App.TicketZoomAttributeBar extends App.Controller
|
|||
constructor: ->
|
||||
super
|
||||
|
||||
@secondaryAction = 'stayOnTab'
|
||||
@secondaryAction = @getAction()
|
||||
|
||||
@subscribeId = App.Macro.subscribe(@checkMacroChanges)
|
||||
@render()
|
||||
|
@ -31,6 +31,9 @@ class App.TicketZoomAttributeBar extends App.Controller
|
|||
@render()
|
||||
)
|
||||
|
||||
getAction: ->
|
||||
return App.Session.get().preferences.secondaryAction || App.Config.get('ticket_secondary_action') || 'stayOnTab'
|
||||
|
||||
release: =>
|
||||
App.Macro.unsubscribe(@subscribeId)
|
||||
|
||||
|
@ -74,6 +77,7 @@ class App.TicketZoomAttributeBar extends App.Controller
|
|||
start: =>
|
||||
return if !@taskbarWatcher
|
||||
@taskbarWatcher.start()
|
||||
@setSecondaryAction(@getAction(), @el)
|
||||
|
||||
stop: =>
|
||||
return if !@taskbarWatcher
|
||||
|
@ -114,11 +118,25 @@ class App.TicketZoomAttributeBar extends App.Controller
|
|||
chooseSecondaryAction: (e) =>
|
||||
type = $(e.currentTarget).find('.js-secondaryActionLabel').data('type')
|
||||
@setSecondaryAction(type, @el)
|
||||
@setUserPreferencesSecondaryAction(type)
|
||||
|
||||
setSecondaryAction: (type, localEl) ->
|
||||
element = localEl.find(".js-secondaryActionLabel[data-type=#{type}]")
|
||||
return @setSecondaryAction('stayOnTab', localEl) if element.length == 0
|
||||
text = element.text()
|
||||
localEl.find('.js-secondaryAction .js-selectedIcon.is-selected').removeClass('is-selected')
|
||||
element.closest('.js-secondaryAction').find('.js-selectedIcon').addClass('is-selected')
|
||||
localEl.find('.js-secondaryActionButtonLabel').text(text)
|
||||
localEl.find('.js-secondaryActionButtonLabel').data('type', type)
|
||||
|
||||
setUserPreferencesSecondaryAction: (type) ->
|
||||
session = App.Session.get()
|
||||
return if session.preferences.secondaryAction is type
|
||||
|
||||
@ajax(
|
||||
id: 'setUserPreferencesSecondaryAction'
|
||||
type: 'PUT'
|
||||
url: "#{App.Config.get('api_path')}/users/preferences"
|
||||
data: JSON.stringify(secondaryAction: type)
|
||||
processData: true
|
||||
)
|
||||
|
|
|
@ -7,7 +7,7 @@ class App.Macro extends App.Model
|
|||
{ name: 'perform', display: 'Actions', tag: 'ticket_perform_action', null: true
|
||||
},
|
||||
{ name: 'ux_flow_next_up', display: 'Once completed...', tag: 'select', default: 'none', options: {
|
||||
none: 'Stay on tab', next_task: 'Close tab', next_from_overview: 'Advance to next ticket from overview'
|
||||
none: 'Stay on tab', next_task: 'Close tab', next_task_on_close: 'Close tab on ticket close', next_from_overview: 'Advance to next ticket from overview'
|
||||
}
|
||||
},
|
||||
{ name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 },
|
||||
|
|
|
@ -10,6 +10,11 @@
|
|||
<span class="dropdown-selectedSpacer js-selectedIcon">
|
||||
<%- @Icon('checkmark') %>
|
||||
</span>
|
||||
<li class="js-secondaryAction" role="menuitem">
|
||||
<span class="js-secondaryActionLabel" data-type="closeTabOnTicketClose"><%- @T('Close tab on ticket close') %></span>
|
||||
<span class="dropdown-selectedSpacer js-selectedIcon">
|
||||
<%- @Icon('checkmark') %>
|
||||
</span>
|
||||
<% if @overview_id: %>
|
||||
<li class="js-secondaryAction" role="menuitem">
|
||||
<span class="js-secondaryActionLabel" data-type="closeNextInOverview"><%- @T('Next in overview') %></span>
|
||||
|
|
|
@ -9,7 +9,7 @@ class Macro < ApplicationModel
|
|||
|
||||
store :perform
|
||||
validates :name, presence: true
|
||||
validates :ux_flow_next_up, inclusion: { in: %w[none next_task next_from_overview] }
|
||||
validates :ux_flow_next_up, inclusion: { in: %w[none next_task next_task_on_close next_from_overview] }
|
||||
|
||||
has_and_belongs_to_many :groups, after_add: :cache_update, after_remove: :cache_update, class_name: 'Group'
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Issue257TicketSecondaryAction < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
# return if it's a new setup
|
||||
return if !Setting.exists?(name: 'system_init_done')
|
||||
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Tab behaviour after ticket action',
|
||||
name: 'ticket_secondary_action',
|
||||
area: 'CustomerWeb::Base',
|
||||
description: 'Defines the tab behaviour after a ticket action.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: true,
|
||||
name: 'ticket_secondary_action',
|
||||
tag: 'boolean',
|
||||
options: {
|
||||
'closeTab' => 'Close tab',
|
||||
'closeTabOnTicketClose' => 'Close tab on ticket close',
|
||||
'closeNextInOverview' => 'Next in overview',
|
||||
'stayOnTab' => 'Stay on tab',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
state: 'stayOnTab',
|
||||
preferences: {
|
||||
authentication: true,
|
||||
permission: ['admin.channel_web'],
|
||||
},
|
||||
frontend: true
|
||||
)
|
||||
end
|
||||
end
|
|
@ -2363,6 +2363,35 @@ Setting.create_if_not_exists(
|
|||
frontend: true
|
||||
)
|
||||
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Tab behaviour after ticket action',
|
||||
name: 'ticket_secondary_action',
|
||||
area: 'CustomerWeb::Base',
|
||||
description: 'Defines the tab behaviour after a ticket action.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: true,
|
||||
name: 'ticket_secondary_action',
|
||||
tag: 'boolean',
|
||||
options: {
|
||||
'closeTab' => 'Close tab',
|
||||
'closeTabOnTicketClose' => 'Close tab on ticket close',
|
||||
'closeNextInOverview' => 'Next in overview',
|
||||
'stayOnTab' => 'Stay on tab',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
state: 'stayOnTab',
|
||||
preferences: {
|
||||
authentication: true,
|
||||
permission: ['admin.channel_web'],
|
||||
},
|
||||
frontend: true
|
||||
)
|
||||
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Enable Ticket creation',
|
||||
name: 'form_ticket_create',
|
||||
|
|
|
@ -1782,4 +1782,128 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Tab behaviour - Define default "stay on tab" / "close tab" behavior #257', authenticated_as: :authenticate do
|
||||
def authenticate
|
||||
Setting.set('ticket_secondary_action', 'closeTabOnTicketClose')
|
||||
true
|
||||
end
|
||||
|
||||
let!(:ticket) { create(:ticket, group: Group.find_by(name: 'Users')) }
|
||||
|
||||
before do
|
||||
visit "ticket/zoom/#{ticket.id}"
|
||||
end
|
||||
|
||||
it 'does show the default of the system' do
|
||||
expect(page).to have_text('Close tab on ticket close')
|
||||
end
|
||||
|
||||
it 'does save state for the user preferences' do
|
||||
click '.js-attributeBar .dropup div'
|
||||
click 'span[data-type=stayOnTab]'
|
||||
refresh
|
||||
expect(page).to have_text('Stay on tab')
|
||||
expect(User.find_by(email: 'admin@example.com').preferences[:secondaryAction]).to eq('stayOnTab')
|
||||
end
|
||||
|
||||
context 'Tab behaviour - Close tab on ticket close' do
|
||||
it 'does not close the tab without any action' do
|
||||
click '.js-submit'
|
||||
expect(current_url).to include('ticket/zoom')
|
||||
end
|
||||
|
||||
it 'does close the tab on ticket close' do
|
||||
select 'closed', from: 'State'
|
||||
click '.js-submit'
|
||||
expect(current_url).not_to include('ticket/zoom')
|
||||
end
|
||||
end
|
||||
|
||||
context 'Tab behaviour - Stay on tab' do
|
||||
def authenticate
|
||||
Setting.set('ticket_secondary_action', 'stayOnTab')
|
||||
true
|
||||
end
|
||||
|
||||
it 'does not close the tab without any action' do
|
||||
click '.js-submit'
|
||||
expect(current_url).to include('ticket/zoom')
|
||||
end
|
||||
|
||||
it 'does not close the tab on ticket close' do
|
||||
select 'closed', from: 'State'
|
||||
click '.js-submit'
|
||||
expect(current_url).to include('ticket/zoom')
|
||||
end
|
||||
end
|
||||
|
||||
context 'Tab behaviour - Close tab' do
|
||||
def authenticate
|
||||
Setting.set('ticket_secondary_action', 'closeTab')
|
||||
true
|
||||
end
|
||||
|
||||
it 'does close the tab without any action' do
|
||||
click '.js-submit'
|
||||
expect(current_url).not_to include('ticket/zoom')
|
||||
end
|
||||
|
||||
it 'does close the tab on ticket close' do
|
||||
select 'closed', from: 'State'
|
||||
click '.js-submit'
|
||||
expect(current_url).not_to include('ticket/zoom')
|
||||
end
|
||||
end
|
||||
|
||||
context 'Tab behaviour - Next in overview' do
|
||||
let(:ticket1) { create(:ticket, title: SecureRandom.uuid, group: Group.find_by(name: 'Users')) }
|
||||
let(:ticket2) { create(:ticket, title: SecureRandom.uuid, group: Group.find_by(name: 'Users')) }
|
||||
let(:ticket3) { create(:ticket, title: SecureRandom.uuid, group: Group.find_by(name: 'Users')) }
|
||||
|
||||
def authenticate
|
||||
Setting.set('ticket_secondary_action', 'closeNextInOverview')
|
||||
ticket1
|
||||
ticket2
|
||||
ticket3
|
||||
true
|
||||
end
|
||||
|
||||
before do
|
||||
visit 'ticket/view/all_open'
|
||||
end
|
||||
|
||||
it 'does change the tab without any action' do
|
||||
click_on ticket1.title
|
||||
expect(current_url).to include("ticket/zoom/#{ticket1.id}")
|
||||
click '.js-submit'
|
||||
expect(current_url).to include("ticket/zoom/#{ticket2.id}")
|
||||
click '.js-submit'
|
||||
expect(current_url).to include("ticket/zoom/#{ticket3.id}")
|
||||
end
|
||||
|
||||
it 'does show default stay on tab if secondary action is not given' do
|
||||
click_on ticket1.title
|
||||
refresh
|
||||
expect(page).to have_text('Stay on tab')
|
||||
end
|
||||
end
|
||||
|
||||
context 'On ticket switch' do
|
||||
let(:ticket1) { create(:ticket, title: SecureRandom.uuid, group: Group.find_by(name: 'Users')) }
|
||||
let(:ticket2) { create(:ticket, title: SecureRandom.uuid, group: Group.find_by(name: 'Users')) }
|
||||
|
||||
before do
|
||||
visit "ticket/zoom/#{ticket1.id}"
|
||||
visit "ticket/zoom/#{ticket2.id}"
|
||||
end
|
||||
|
||||
it 'does setup the last behaviour' do
|
||||
click '.js-attributeBar .dropup div'
|
||||
click 'span[data-type=stayOnTab]'
|
||||
visit "ticket/zoom/#{ticket1.id}"
|
||||
expect(page).to have_text('Stay on tab')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue