Removed macro event for TicketCreateFormHandler. This is not needed, because there are no macros when creating tickets.

This commit is contained in:
Denny Korsukéwitz 2019-09-04 09:42:50 +02:00 committed by Thorsten Eckel
parent 7e2f55d91f
commit feac4bb938
13 changed files with 284 additions and 53 deletions

View file

@ -87,9 +87,9 @@ class App.TicketOverview extends App.Controller
startDragItem: (event) =>
return if !@batchSupport
@grabbedItem = $(event.currentTarget)
offset = @grabbedItem.offset()
@batchDragger = $(App.view('ticket_overview/batch_dragger')())
@grabbedItem = $(event.currentTarget)
offset = @grabbedItem.offset()
@batchDragger = $(App.view('ticket_overview/batch_dragger')())
@grabbedItemClone = @grabbedItem.clone()
@grabbedItemClone.data('offset', @grabbedItem.offset())
@grabbedItemClone.addClass('batch-dragger-item js-main-item')
@ -642,10 +642,35 @@ class App.TicketOverview extends App.Controller
))
renderOptionsMacros: =>
macros = App.Macro.search(filter: { active: true }, sortBy:'name', order:'DESC')
@possibleMacros = []
macros = App.Macro.search(filter: { active: true }, sortBy:'name', order:'DESC')
items = @el.find('[name="bulk"]:checked')
group_ids =[]
for item in items
ticket = App.Ticket.find($(item).val())
group_ids.push ticket.group_id
group_ids = _.uniq(group_ids)
for macro in macros
# push if no group_ids exists
if _.isEmpty(macro.group_ids) && !_.includes(@possibleMacros, macro)
@possibleMacros.push macro
# push if group_ids are equal
if _.isEqual(macro.group_ids, group_ids) && !_.includes(@possibleMacros, macro)
@possibleMacros.push macro
# push if all group_ids of tickets are in macro.group_ids
if !_.isEmpty(macro.group_ids) && _.isEmpty(_.difference(group_ids,macro.group_ids)) && !_.includes(@possibleMacros, macro)
@possibleMacros.push macro
@batchMacro.html $(App.view('ticket_overview/batch_overlay_macro')(
macros: macros
macros: @possibleMacros
))
active: (state) =>

View file

@ -1,7 +1,7 @@
class App.TicketZoomAttributeBar extends App.Controller
elements:
'.js-submitDropdown': 'buttonDropdown'
'.js-reset': 'resetButton'
'.js-reset': 'resetButton'
events:
'mousedown .js-openDropdownMacro': 'toggleMacroMenu'
@ -11,6 +11,7 @@ class App.TicketZoomAttributeBar extends App.Controller
'mouseleave .js-dropdownActionMacro': 'onActionMacroMouseLeave'
'click .js-secondaryAction': 'chooseSecondaryAction'
searchCondition: {}
constructor: ->
super
@ -24,6 +25,12 @@ class App.TicketZoomAttributeBar extends App.Controller
@render()
)
@bind('MacroPreconditionUpdate', (data) =>
return if data.taskKey isnt @taskKey
@searchCondition = data.params
@render()
)
release: =>
App.Macro.unsubscribe(@subscribeId)
@ -34,16 +41,24 @@ class App.TicketZoomAttributeBar extends App.Controller
if @resetButton.get(0) && !@resetButton.hasClass('hide')
resetButtonShown = true
macros = App.Macro.findAllByAttribute('active', true)
macros = App.Macro.search(filter: { active: true }, sortBy:'name', order:'DESC')
@macroLastUpdated = App.Macro.lastUpdatedAt()
@possibleMacros = []
if _.isEmpty(macros) || !@permissionCheck('ticket.agent')
macroDisabled = true
else
for macro in macros
if !_.isEmpty(macro.group_ids) && @searchCondition.group_id && !_.includes(macro.group_ids, parseInt(@searchCondition.group_id))
continue
@possibleMacros.push macro
localeEl = $(App.view('ticket_zoom/attribute_bar')(
macros: macros
macroDisabled: macroDisabled
overview_id: @overview_id
macros: @possibleMacros
macroDisabled: macroDisabled
overview_id: @overview_id
resetButtonShown: resetButtonShown
))
@setSecondaryAction(@secondaryAction, localeEl)

View file

@ -0,0 +1,11 @@
class TicketZoomFormHandlerMacro
# central method, is getting called on every ticket form change
# but only trigger event for group_id changes
@run: (params, attribute, attributes, classname, form, ui) ->
return if attribute.name isnt 'group_id'
App.Event.trigger('MacroPreconditionUpdate', { taskKey: ui.taskKey, params: params })
App.Config.set('120-ticketFormMacro', TicketZoomFormHandlerMacro, 'TicketZoomFormHandler')

View file

@ -1,57 +1,26 @@
class App.Macro extends App.Model
@configure 'Macro', 'name', 'perform', 'ux_flow_next_up', 'note', 'active'
@configure 'Macro', 'name', 'perform', 'ux_flow_next_up', 'note', 'group_ids', 'active'
@extend Spine.Model.Ajax
@url: @apiPath + '/macros'
@configure_attributes = [
{
name: 'name',
display: 'Name',
tag: 'input',
type: 'text',
limit: 100,
null: false
{ name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, null: false },
{ name: 'perform', display: 'Actions', tag: 'ticket_perform_action', null: true
},
{
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'
{ 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'
}
},
{
name: 'updated_at',
display: 'Updated',
tag: 'datetime',
readonly: 1
},
{
name: 'note',
display: 'Note',
tag: 'textarea',
limit: 250,
null: true
},
{
name: 'active',
display: 'Active',
tag: 'active',
default: true
},
{ name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 },
{ name: 'note', display: 'Note', tag: 'textarea', limit: 250, null: true },
{ name: 'group_ids', display: 'Groups', tag: 'column_select', relation: 'Group', null: true },
{ name: 'active', display: 'Active', tag: 'active', default: true },
]
@configure_delete = true
@configure_clone = true
@configure_overview = [
'name',
'note',
'group_ids',
]
@description = '''

View file

@ -8,4 +8,6 @@ class Macro < ApplicationModel
store :perform
validates :name, presence: true
validates :ux_flow_next_up, inclusion: { in: %w[none next_task next_from_overview] }
has_and_belongs_to_many :groups, after_add: :cache_update, after_remove: :cache_update, class_name: 'Group'
end

View file

@ -0,0 +1,18 @@
class GroupDependentMacros < ActiveRecord::Migration[4.2]
def up
create_table :groups_macros, id: false do |t| # rubocop:disable Rails/CreateTableWithTimestamps
t.references :macro, null: false
t.references :group, null: false
end
add_index :groups_macros, [:macro_id]
add_index :groups_macros, [:group_id]
add_foreign_key :groups_macros, :macros
add_foreign_key :groups_macros, :groups
end
def self.down
drop_table :groups_macros
end
end

View file

@ -1,7 +1,7 @@
FactoryBot.define do
factory :macro do
sequence(:name) { |n| "Macro #{n}" }
perform { {} }
perform { { 'ticket.state_id' => { 'value' => 1 } } }
ux_flow_next_up { 'next_task' }
note { '' }
active { true }

View file

@ -27,6 +27,37 @@ module BrowserTestHelper
Waiter.new(wait_handle)
end
# Moves the mouse from its current position by the given offset.
# If the coordinates provided are outside the viewport (the mouse will end up outside the browser window)
# then the viewport is scrolled to match.
#
# @example
# move_mouse_by(x, y)
# move_mouse_by(100, 200)
#
def move_mouse_by(x_axis, y_axis)
page.driver.browser.action.move_by(x_axis, y_axis).perform
end
# Clicks and hold (without releasing) in the middle of the given element.
#
# @example
# click_and_hold(ticket)
# click_and_hold(tr[data-id='1'])
#
def click_and_hold(element)
page.driver.browser.action.click_and_hold(element).perform
end
# Releases the depressed left mouse button at the current mouse location.
#
# @example
# release_mouse
#
def release_mouse
page.driver.browser.action.release.perform
end
class Waiter < SimpleDelegator
# This method is a derivation of Selenium::WebDriver::Wait#until

View file

@ -173,6 +173,16 @@ module CommonActions
page.driver.browser.navigate.refresh
attribute
end
# opens the macro list in the ticket view via click
#
# @example
# open_macro_list
#
def open_macro_list
click '.js-openDropdownMacro'
end
end
RSpec.configure do |config|

View file

@ -23,3 +23,15 @@ end
Capybara.add_selector(:text_module) do
css { |id| %(.shortcut > ul > li[data-id="#{id}"]) }
end
Capybara.add_selector(:macro) do
css { |id| %(.js-submitDropdown > ul > li[data-id="#{id}"]) }
end
Capybara.add_selector(:macro_batch) do
css { |id| %(.batch-overlay-macro-entry[data-id='#{id}']) }
end
Capybara.add_selector(:table_row) do
css { |id| %(tr[data-id='#{id}']) }
end

View file

@ -0,0 +1,45 @@
RSpec.shared_examples 'macros' do |path:|
let!(:group1) { create :group }
let!(:group2) { create :group }
let!(:macro_without_group) { create :macro }
let!(:macro_group1) { create :macro, groups: [group1] }
let!(:macro_group2) { create :macro, groups: [group2] }
it 'supports group-dependent macros' do
# give user access to all groups including those created
# by using FactoryBot outside of the example
group_names_access_map = Group.all.pluck(:name).each_with_object({}) do |group_name, result|
result[group_name] = 'full'.freeze
end
current_user do |user|
user.group_names_access_map = group_names_access_map
user.save!
end
# refresh browser to get macro accessable
refresh
visit path
within(:active_content) do
# select group
find('select[name="group_id"]').select(group1.name)
open_macro_list
expect(page).to have_selector(:macro, macro_without_group.id)
expect(page).to have_selector(:macro, macro_group1.id)
expect(page).to have_no_selector(:macro, macro_group2.id)
# select group
find('select[name="group_id"]').select(group2.name)
open_macro_list
expect(page).to have_selector(:macro, macro_without_group.id)
expect(page).to have_no_selector(:macro, macro_group1.id)
expect(page).to have_selector(:macro, macro_group2.id)
end
end
end

View file

@ -1,6 +1,7 @@
require 'rails_helper'
require 'system/examples/text_modules_examples'
require 'system/examples/macros_examples'
RSpec.describe 'Ticket Update', type: :system do
@ -141,4 +142,8 @@ RSpec.describe 'Ticket Update', type: :system do
context 'when using text modules' do
include_examples 'text modules', path: "#ticket/zoom/#{Ticket.first.id}"
end
context 'when using macros' do
include_examples 'macros', path: "#ticket/zoom/#{Ticket.first.id}"
end
end

View file

@ -0,0 +1,88 @@
require 'rails_helper'
RSpec.describe 'Ticket views', type: :system do
let!(:group1) { create :group }
let!(:group2) { create :group }
let!(:macro_without_group) { create :macro }
let!(:macro_group1) { create :macro, groups: [group1] }
let!(:macro_group2) { create :macro, groups: [group2] }
it 'supports group-dependent macros' do
ticket1 = create :ticket, group: group1
ticket2 = create :ticket, group: group2
# give user access to all groups including those created
# by using FactoryBot outside of the example
group_names_access_map = Group.all.pluck(:name).each_with_object({}) do |group_name, result|
result[group_name] = 'full'.freeze
end
current_user do |user|
user.group_names_access_map = group_names_access_map
user.save!
end
# refresh browser to get macro accessable
refresh
visit '#ticket/view/all_open'
within(:active_content) do
ticket = page.find(:table_row, 1).native
# click and hold first ticket in table
click_and_hold(ticket)
# move ticket to y -ticket.location.y
move_mouse_by(0, -ticket.location.y + 5)
# move a bit to the left to display macro batches
move_mouse_by(-250, 0)
expect(page).to have_selector(:macro_batch, macro_without_group.id, visible: true)
expect(page).to have_no_selector(:macro_batch, macro_group1.id)
expect(page).to have_no_selector(:macro_batch, macro_group2.id)
release_mouse
refresh
ticket = page.find(:table_row, ticket1.id).native
# click and hold first ticket in table
click_and_hold(ticket)
# move ticket to y -ticket.location.y
move_mouse_by(0, -ticket.location.y + 5)
# move a bit to the left to display macro batches
move_mouse_by(-250, 0)
expect(page).to have_selector(:macro_batch, macro_without_group.id, visible: true)
expect(page).to have_selector(:macro_batch, macro_group1.id)
expect(page).to have_no_selector(:macro_batch, macro_group2.id)
release_mouse
refresh
ticket = page.find(:table_row, ticket2.id).native
# click and hold first ticket in table
click_and_hold(ticket)
# move ticket to y -ticket.location.y
move_mouse_by(0, -ticket.location.y + 5)
# move a bit to the left to display macro batches
move_mouse_by(-250, 0)
expect(page).to have_selector(:macro_batch, macro_without_group.id, visible: true)
expect(page).to have_no_selector(:macro_batch, macro_group1.id)
expect(page).to have_selector(:macro_batch, macro_group2.id)
end
end
end