<%- @Icon('diagonal-cross') %>
diff --git a/app/assets/stylesheets/zammad.scss b/app/assets/stylesheets/zammad.scss
index 82b143649..97b867b27 100644
--- a/app/assets/stylesheets/zammad.scss
+++ b/app/assets/stylesheets/zammad.scss
@@ -4285,6 +4285,12 @@ footer {
.navigation .nav-tab-name {
text-align: start;
+
+
+ &.is-inactive {
+ text-decoration: line-through;
+ opacity: .73;
+ }
}
.tasks-navigation .nav-tab-icon .error {
@@ -4314,6 +4320,11 @@ footer {
.nav-tab.nav-tab--search {
height: 30px;
padding-top: 9px;
+
+ &.is-inactive {
+ text-decoration: line-through;
+ opacity: .73;
+ }
}
.nav-tab-icon {
@@ -5353,6 +5364,11 @@ footer {
border: none;
background: none;
padding: 21px 17px 4px;
+
+ .is-inactive {
+ text-decoration: line-through;
+ color: #ccc;
+ }
}
.popover-content {
@@ -5411,10 +5427,22 @@ footer {
color: #a1a4a7;
}
+ .popover .person {
+ &.is-inactive {
+ text-decoration: line-through;
+ color: #ccc;
+ }
+ }
+
.popover .user-organization {
@extend .u-textTruncate;
margin-bottom: 8px;
margin-top: -4px;
+
+ &.is-inactive {
+ text-decoration: line-through;
+ color: #ccc;
+ }
}
.popover-block {
@@ -5555,6 +5583,11 @@ footer {
top: 0;
}
+ .user-popover.is-inactive {
+ text-decoration: line-through;
+ opacity: .73;
+ }
+
.btn.js-newTicket {
position: absolute;
right: 0;
@@ -7996,6 +8029,11 @@ footer {
padding: 9px 15px;
list-style-image: none;
+ &.is-inactive {
+ text-decoration: line-through;
+ opacity: .73;
+ }
+
&:not(:first-child) {
box-shadow: 0 1px rgba(255,255,255,.13) inset;
}
@@ -8566,6 +8604,13 @@ footer {
display: flex;
align-items: center;
@extend .u-clickable;
+
+ &.is-inactive {
+ .recipientList-name {
+ text-decoration: line-through;
+ opacity: .73;
+ }
+ }
}
.recipientList-entry .recipientList-iconSpacer {
@@ -8620,6 +8665,10 @@ footer {
.recipientList-detail {
opacity: 0.5;
+
+ &.is-inactive > span {
+ text-decoration: line-through;
+ }
}
.recipientList-icon.plus {
@@ -10354,6 +10403,11 @@ output {
& + .icon {
@include bidi-style(margin-left, 10px, margin-right, 0);
}
+
+ &.is-inactive {
+ opacity: .73;
+ text-decoration: line-through;
+ }
}
&.dropdown li {
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index b0cff0c23..bfe1e4b7b 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -282,7 +282,7 @@ class UsersController < ApplicationController
realname = "#{realname} <#{user.email}>"
end
a = if params[:term]
- { id: user.id, label: realname, value: user.email }
+ { id: user.id, label: realname, value: user.email, inactive: !user.active }
else
{ id: user.id, label: realname, value: realname }
end
diff --git a/spec/requests/user_spec.rb b/spec/requests/user_spec.rb
index af925f855..a402e6fdb 100644
--- a/spec/requests/user_spec.rb
+++ b/spec/requests/user_spec.rb
@@ -65,6 +65,18 @@ RSpec.describe 'User', type: :request do
)
end
+ let!(:customer_inactive) do
+ create(
+ :customer,
+ organization: organization,
+ login: 'rest-customer_inactive@example.com',
+ firstname: 'Rest',
+ lastname: 'CustomerInactive',
+ email: 'rest-customer_inactive@example.com',
+ active: false,
+ )
+ end
+
before do
configure_elasticsearch(rebuild: true)
end
@@ -224,7 +236,7 @@ RSpec.describe 'User', type: :request do
get '/api/v1/users/me', params: {}, as: :json
expect(response).to have_http_status(:ok)
expect(json_response).to be_truthy
- expect('rest-admin@example.com').to eq(json_response['email'])
+ expect(json_response['email']).to eq('rest-admin@example.com')
# index
get '/api/v1/users', params: {}, as: :json
@@ -243,13 +255,13 @@ RSpec.describe 'User', type: :request do
expect(response).to have_http_status(:ok)
expect(json_response).to be_truthy
expect(Hash).to eq(json_response.class)
- expect('rest-agent@example.com').to eq(json_response['email'])
+ expect(json_response['email']).to eq('rest-agent@example.com')
get "/api/v1/users/#{customer.id}", params: {}, as: :json
expect(response).to have_http_status(:ok)
expect(json_response).to be_truthy
expect(Hash).to eq(json_response.class)
- expect('rest-customer1@example.com').to eq(json_response['email'])
+ expect(json_response['email']).to eq('rest-customer1@example.com')
# create user with admin role
role = Role.lookup(name: 'Admin')
@@ -332,7 +344,7 @@ RSpec.describe 'User', type: :request do
get '/api/v1/users/me', params: {}, as: :json
expect(response).to have_http_status(:ok)
expect(json_response).to be_truthy
- expect('rest-agent@example.com').to eq(json_response['email'])
+ expect(json_response['email']).to eq('rest-agent@example.com')
# index
get '/api/v1/users', params: {}, as: :json
@@ -442,9 +454,15 @@ RSpec.describe 'User', type: :request do
expect(json_response[0]['id']).to eq(json_response1['id'])
expect(json_response[0]['label']).to eq("Customer#{firstname} Customer Last ")
expect(json_response[0]['value']).to eq('new_customer_by_agent@example.com')
+ expect(json_response[0]['inactive']).to eq(false)
expect(json_response[0]['role_ids']).to be_falsey
expect(json_response[0]['roles']).to be_falsey
+ get "/api/v1/users/search?term=#{CGI.escape('CustomerInactive')}", params: {}, as: :json
+ expect(response).to have_http_status(:ok)
+ expect(json_response).to be_a_kind_of(Array)
+ expect(json_response[0]['inactive']).to eq(true)
+
# Regression test for issue #2539 - search pagination broken in users_controller.rb
# Get the total number of users N, then search with one result per page, so there should N pages with one result each
get '/api/v1/users/search', params: { query: '*' }, as: :json
@@ -494,19 +512,19 @@ RSpec.describe 'User', type: :request do
get '/api/v1/users/me', params: {}, as: :json
expect(response).to have_http_status(:ok)
expect(json_response).to be_truthy
- expect('rest-customer1@example.com').to eq(json_response['email'])
+ expect(json_response['email']).to eq('rest-customer1@example.com')
# index
get '/api/v1/users', params: {}, as: :json
expect(response).to have_http_status(:ok)
expect(Array).to eq(json_response.class)
- expect(1).to eq(json_response.length)
+ expect(json_response.length).to eq(1)
# show/:id
get "/api/v1/users/#{customer.id}", params: {}, as: :json
expect(response).to have_http_status(:ok)
expect(Hash).to eq(json_response.class)
- expect('rest-customer1@example.com').to eq(json_response['email'])
+ expect(json_response['email']).to eq('rest-customer1@example.com')
get "/api/v1/users/#{customer2.id}", params: {}, as: :json
expect(response).to have_http_status(:forbidden)
@@ -536,19 +554,19 @@ RSpec.describe 'User', type: :request do
get '/api/v1/users/me', params: {}, as: :json
expect(response).to have_http_status(:ok)
expect(json_response).to be_truthy
- expect('rest-customer2@example.com').to eq(json_response['email'])
+ expect(json_response['email']).to eq('rest-customer2@example.com')
# index
get '/api/v1/users', params: {}, as: :json
expect(response).to have_http_status(:ok)
expect(Array).to eq(json_response.class)
- expect(1).to eq(json_response.length)
+ expect(json_response.length).to eq(1)
# show/:id
get "/api/v1/users/#{customer2.id}", params: {}, as: :json
expect(response).to have_http_status(:ok)
expect(Hash).to eq(json_response.class)
- expect('rest-customer2@example.com').to eq(json_response['email'])
+ expect(json_response['email']).to eq('rest-customer2@example.com')
get "/api/v1/users/#{customer.id}", params: {}, as: :json
expect(response).to have_http_status(:forbidden)
diff --git a/spec/system/manage/users_spec.rb b/spec/system/manage/users_spec.rb
index d5f715239..807265796 100644
--- a/spec/system/manage/users_spec.rb
+++ b/spec/system/manage/users_spec.rb
@@ -69,8 +69,25 @@ RSpec.describe 'Manage > Users', type: :system do
expect(page).to have_css('table.user-list td', text: 'NewTestUserFirstName')
end
-
end
+ describe 'select an Organization' do
+ before do
+ create(:organization, name: 'Example Inc.', active: true)
+ create(:organization, name: 'Inactive Inc.', active: false)
+ end
+
+ it 'check for inactive Organizations in Organization selection' do
+ visit '#manage/users'
+
+ within(:active_content) do
+ find('[data-type=new]').click
+
+ find('[name=organization_id] ~ .searchableSelect-main').fill_in with: '**'
+ expect(page).to have_css('ul.js-optionsList > li.js-option', minimum: 2)
+ expect(page).to have_css('ul.js-optionsList > li.js-option .is-inactive', count: 1)
+ end
+ end
+ end
end
end
diff --git a/spec/system/search_spec.rb b/spec/system/search_spec.rb
index 9b664f6db..df85a5759 100644
--- a/spec/system/search_spec.rb
+++ b/spec/system/search_spec.rb
@@ -16,4 +16,37 @@ RSpec.describe 'Search', type: :system, searchindex: true do
expect(page).to have_text '"Welcome"'
end
end
+
+ context 'inactive user and organizations' do
+ before do
+ create(:organization, name: 'Example Inc.', active: true)
+ create(:organization, name: 'Example Inactive Inc.', active: false)
+ create(:customer, firstname: 'Firstname', lastname: 'Active', active: true)
+ create(:customer, firstname: 'Firstname', lastname: 'Inactive', active: false)
+
+ configure_elasticsearch(rebuild: true)
+ end
+
+ it 'check that inactive organizations are marked correctly' do
+ fill_in id: 'global-search', with: '"Example"'
+
+ expect(page).to have_css('.nav-tab--search.organization', minimum: 2)
+ expect(page).to have_css('.nav-tab--search.organization.is-inactive', count: 1)
+ end
+
+ it 'check that inactive users are marked correctly' do
+ fill_in id: 'global-search', with: '"Firstname"'
+
+ expect(page).to have_css('.nav-tab--search.user', minimum: 2)
+ expect(page).to have_css('.nav-tab--search.user.is-inactive', count: 1)
+ end
+
+ it 'check that inactive users are also marked in the popover for the quick search result' do
+ fill_in id: 'global-search', with: '"Firstname"'
+
+ popover_on_hover(find('.nav-tab--search.user.is-inactive'))
+
+ expect(page).to have_css('.popover-title .is-inactive', count: 1)
+ end
+ end
end
diff --git a/spec/system/ticket/create_spec.rb b/spec/system/ticket/create_spec.rb
index 6455d8b84..fc64636a7 100644
--- a/spec/system/ticket/create_spec.rb
+++ b/spec/system/ticket/create_spec.rb
@@ -456,4 +456,21 @@ RSpec.describe 'Ticket Create', type: :system do
expect(page).to have_no_selector(:task_with, task_key)
end
end
+
+ describe 'customer selection to check the field search' do
+ before do
+ create(:customer, active: true)
+ create(:customer, active: false)
+ end
+
+ it 'check for inactive customer in customer/organization selection' do
+ visit 'ticket/create'
+
+ within(:active_content) do
+ find('[name=customer_id] ~ .user-select.token-input').fill_in with: '**'
+ expect(page).to have_css('ul.recipientList > li.recipientList-entry', minimum: 2)
+ expect(page).to have_css('ul.recipientList > li.recipientList-entry.is-inactive', count: 1)
+ end
+ end
+ end
end
diff --git a/spec/system/ticket/zoom_spec.rb b/spec/system/ticket/zoom_spec.rb
index eec68e6a4..14a8b2ed4 100644
--- a/spec/system/ticket/zoom_spec.rb
+++ b/spec/system/ticket/zoom_spec.rb
@@ -208,10 +208,14 @@ RSpec.describe 'Ticket zoom', type: :system do
context 'to inbound phone call', current_user_id: -> { agent.id }, authenticated_as: -> { agent } do
let(:agent) { create(:agent, groups: [Group.first]) }
- let(:customer) { create(:agent) }
+ let(:customer) { create(:customer) }
let(:ticket) { create(:ticket, customer: customer, group: agent.groups.first) }
let!(:article) { create(:ticket_article, :inbound_phone, ticket: ticket) }
+ before do
+ create(:customer, active: false)
+ end
+
it 'goes to customer email' do
visit "ticket/zoom/#{ticket.id}"
@@ -225,11 +229,28 @@ RSpec.describe 'Ticket zoom', type: :system do
end
end
end
+
+ it 'check active and inactive user in TO-field' do
+ visit "ticket/zoom/#{ticket.id}"
+
+ within :active_ticket_article, article do
+ click '.js-ArticleAction[data-type=emailReply]'
+ end
+
+ within :active_content do
+ within '.article-new' do
+ find('[name=to] ~ .ui-autocomplete-input').fill_in with: '**'
+ end
+ end
+
+ expect(page).to have_css('ul.ui-autocomplete > li.ui-menu-item', minimum: 2)
+ expect(page).to have_css('ul.ui-autocomplete > li.ui-menu-item.is-inactive', count: 1)
+ end
end
context 'to outbound phone call', current_user_id: -> { agent.id }, authenticated_as: -> { agent } do
let(:agent) { create(:agent, groups: [Group.first]) }
- let(:customer) { create(:agent) }
+ let(:customer) { create(:customer) }
let(:ticket) { create(:ticket, customer: customer, group: agent.groups.first) }
let!(:article) { create(:ticket_article, :outbound_phone, ticket: ticket) }