diff --git a/app/javascript/dashboard/composables/spec/useMacros.spec.js b/app/javascript/dashboard/composables/spec/useMacros.spec.js index 7666e4afa..ed6a7bc87 100644 --- a/app/javascript/dashboard/composables/spec/useMacros.spec.js +++ b/app/javascript/dashboard/composables/spec/useMacros.spec.js @@ -119,24 +119,27 @@ describe('useMacros', () => { const { getMacroDropdownValues } = useMacros(); expect(getMacroDropdownValues('add_label')).toHaveLength(mockLabels.length); expect(getMacroDropdownValues('assign_team')).toHaveLength( - mockTeams.length - ); + mockTeams.length + 1 + ); // +1 for "None" expect(getMacroDropdownValues('assign_agent')).toHaveLength( - mockAgents.length + 1 - ); // +1 for "Self" + mockAgents.length + 2 + ); // +2 for "None" and "Self" }); - it('returns teams for assign_team and send_email_to_team types', () => { + it('returns teams with "None" option for assign_team and teams only for send_email_to_team', () => { const { getMacroDropdownValues } = useMacros(); - expect(getMacroDropdownValues('assign_team')).toEqual(mockTeams); + const assignTeamResult = getMacroDropdownValues('assign_team'); + expect(assignTeamResult[0]).toEqual({ id: 'nil', name: 'AUTOMATION.NONE_OPTION' }); + expect(assignTeamResult.slice(1)).toEqual(mockTeams); expect(getMacroDropdownValues('send_email_to_team')).toEqual(mockTeams); }); - it('returns agents with "Self" option for assign_agent type', () => { + it('returns agents with "None" and "Self" options for assign_agent type', () => { const { getMacroDropdownValues } = useMacros(); const result = getMacroDropdownValues('assign_agent'); - expect(result[0]).toEqual({ id: 'self', name: 'Self' }); - expect(result.slice(1)).toEqual(mockAgents); + expect(result[0]).toEqual({ id: 'nil', name: 'AUTOMATION.NONE_OPTION' }); + expect(result[1]).toEqual({ id: 'self', name: 'Self' }); + expect(result.slice(2)).toEqual(mockAgents); }); it('returns formatted labels for add_label and remove_label types', () => { @@ -172,8 +175,11 @@ describe('useMacros', () => { const { getMacroDropdownValues } = useMacros(); expect(getMacroDropdownValues('add_label')).toEqual([]); - expect(getMacroDropdownValues('assign_team')).toEqual([]); + expect(getMacroDropdownValues('assign_team')).toEqual([ + { id: 'nil', name: 'AUTOMATION.NONE_OPTION' }, + ]); expect(getMacroDropdownValues('assign_agent')).toEqual([ + { id: 'nil', name: 'AUTOMATION.NONE_OPTION' }, { id: 'self', name: 'Self' }, ]); }); diff --git a/app/javascript/dashboard/composables/useMacros.js b/app/javascript/dashboard/composables/useMacros.js index 8f0227fa3..11ed5b424 100644 --- a/app/javascript/dashboard/composables/useMacros.js +++ b/app/javascript/dashboard/composables/useMacros.js @@ -23,10 +23,18 @@ export const useMacros = () => { const getMacroDropdownValues = type => { switch (type) { case 'assign_team': + return [ + { id: 'nil', name: t('AUTOMATION.NONE_OPTION') }, + ...teams.value, + ]; case 'send_email_to_team': return teams.value; case 'assign_agent': - return [{ id: 'self', name: 'Self' }, ...agents.value]; + return [ + { id: 'nil', name: t('AUTOMATION.NONE_OPTION') }, + { id: 'self', name: 'Self' }, + ...agents.value, + ]; case 'add_label': case 'remove_label': return labels.value.map(i => ({ diff --git a/app/javascript/dashboard/routes/dashboard/settings/macros/constants.js b/app/javascript/dashboard/routes/dashboard/settings/macros/constants.js index e8ee4fdef..e510a5304 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/macros/constants.js +++ b/app/javascript/dashboard/routes/dashboard/settings/macros/constants.js @@ -19,6 +19,8 @@ export const MACRO_ACTION_TYPES = [ label: 'REMOVE_LABEL', inputType: 'multi_select', }, + // @deprecated: Use assign_team with 'None' option instead + // Kept for backward compatibility { key: 'remove_assigned_team', label: 'REMOVE_ASSIGNED_TEAM', diff --git a/app/javascript/dashboard/routes/dashboard/settings/macros/macroHelper.js b/app/javascript/dashboard/routes/dashboard/settings/macros/macroHelper.js index 3fc204ac0..c498ac4e3 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/macros/macroHelper.js +++ b/app/javascript/dashboard/routes/dashboard/settings/macros/macroHelper.js @@ -17,6 +17,7 @@ export const resolveActionName = key => { export const resolveTeamIds = (teams, ids) => { return ids .map(id => { + if (id === 'nil') return 'None'; const team = teams.find(i => i.id === id); return team ? team.name : ''; }) @@ -35,6 +36,8 @@ export const resolveLabels = (labels, ids) => { export const resolveAgents = (agents, ids) => { return ids .map(id => { + if (id === 'nil') return 'None'; + if (id === 'self') return 'Self'; const agent = agents.find(i => i.id === id); return agent ? agent.name : ''; }) diff --git a/app/services/action_service.rb b/app/services/action_service.rb index a50b11193..2266f0ea5 100644 --- a/app/services/action_service.rb +++ b/app/services/action_service.rb @@ -66,6 +66,8 @@ class ActionService @conversation.update!(team_id: team_ids[0]) end + # @deprecated Use assign_team with 'nil' value instead + # This method is kept for backward compatibility def remove_assigned_team(_params) @conversation.update!(team_id: nil) end diff --git a/spec/services/macros/execution_service_spec.rb b/spec/services/macros/execution_service_spec.rb index b5bf13044..d5ca87422 100644 --- a/spec/services/macros/execution_service_spec.rb +++ b/spec/services/macros/execution_service_spec.rb @@ -49,6 +49,19 @@ RSpec.describe Macros::ExecutionService, type: :service do end end + describe '#assign_team' do + let(:team) { create(:team, account: account) } + + context 'when team_id is nil' do + it 'unassigns the team from the conversation' do + # Directly set the team_id to avoid auto-assignment logic + conversation.update_column(:team_id, team.id) + service.send(:assign_team, ['nil']) + expect(conversation.reload.team).to be_nil + end + end + end + describe '#assign_agent' do context 'when agent_ids contains self' do it 'updates the conversation assignee to the current user' do @@ -69,6 +82,14 @@ RSpec.describe Macros::ExecutionService, type: :service do expect(conversation.reload.assignee).to eq(other_user) end end + + context 'when agent_ids contains nil' do + it 'unassigns the conversation' do + conversation.update!(assignee: user) + service.send(:assign_agent, ['nil']) + expect(conversation.reload.assignee).to be_nil + end + end end describe '#add_private_note' do