[FIX] Mark agents as unavailable when they logout (#23219)

* Mark agents as unavailable when logout

* Honor BH setting before making agent available

* Respect business hours config before activating user on login

* change to oneliners

* Apply translations on Livechat Status field on Agent info screen

Co-authored-by: Renato Becker <renato.augusto.becker@gmail.com>
Co-authored-by: murtaza98 <murtaza.patrawala@rocket.chat>
pull/23254/head^2
Kevin Aleman 4 years ago committed by GitHub
parent d8a779a0e4
commit 8bfe7ada6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      app/livechat/server/business-hour/AbstractBusinessHour.ts
  2. 9
      app/livechat/server/business-hour/BusinessHourManager.ts
  3. 3
      app/livechat/server/business-hour/index.ts
  4. 2
      app/livechat/server/lib/Livechat.js
  5. 4
      app/livechat/server/startup.js
  6. 32
      app/models/server/raw/Users.js
  7. 4
      client/views/omnichannel/agents/AgentInfo.js

@ -19,6 +19,7 @@ export interface IBusinessHourBehavior {
onStartBusinessHours(): Promise<void>;
afterSaveBusinessHours(businessHourData: ILivechatBusinessHour): Promise<void>;
allowAgentChangeServiceStatus(agentId: string): Promise<boolean>;
changeAgentActiveStatus(agentId: string, status: string): Promise<any>;
}
export interface IBusinessHourType {
@ -44,6 +45,10 @@ export abstract class AbstractBusinessHourBehavior {
async allowAgentChangeServiceStatus(agentId: string): Promise<boolean> {
return this.UsersRepository.isAgentWithinBusinessHours(agentId);
}
async changeAgentActiveStatus(agentId: string, status: string): Promise<any> {
return this.UsersRepository.setLivechatStatus(agentId, status);
}
}
export abstract class AbstractBusinessHourType {

@ -5,6 +5,7 @@ import { ICronJobs } from '../../../utils/server/lib/cron/Cronjobs';
import { IBusinessHourBehavior, IBusinessHourType } from './AbstractBusinessHour';
import { settings } from '../../../settings/server';
import { callbacks } from '../../../callbacks/server';
import { Users } from '../../../models/server/raw';
const cronJobDayDict: Record<string, number> = {
Sunday: 0,
@ -86,6 +87,14 @@ export class BusinessHourManager {
await this.createCronJobsForWorkHours();
}
async onLogin(agentId: string): Promise<any> {
if (!settings.get('Livechat_enable_business_hours')) {
return this.behavior.changeAgentActiveStatus(agentId, 'available');
}
return Users.setLivechatStatusActiveBasedOnBusinessHours(agentId);
}
private setupCallbacks(): void {
callbacks.add('livechat.removeAgentDepartment', this.behavior.onRemoveAgentFromDepartment.bind(this), callbacks.priority.HIGH, 'business-hour-livechat-on-remove-agent-department');
callbacks.add('livechat.afterRemoveDepartment', this.behavior.onRemoveDepartment.bind(this), callbacks.priority.HIGH, 'business-hour-livechat-after-remove-department');

@ -1,4 +1,5 @@
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import { BusinessHourManager } from './BusinessHourManager';
import { SingleBusinessHourBehavior } from './Single';
@ -12,4 +13,6 @@ Meteor.startup(() => {
const { BusinessHourBehaviorClass } = callbacks.run('on-business-hour-start', { BusinessHourBehaviorClass: SingleBusinessHourBehavior });
businessHourManager.registerBusinessHourBehavior(new BusinessHourBehaviorClass());
businessHourManager.registerBusinessHourType(new DefaultBusinessHour());
Accounts.onLogin(async ({ user }: { user: any }) => user?.roles?.includes('livechat-agent') && businessHourManager.onLogin(user._id));
});

@ -810,7 +810,7 @@ export const Livechat = {
if (addUserRoles(user._id, 'livechat-agent')) {
Users.setOperator(user._id, true);
this.setUserStatusLivechat(user._id, 'available');
this.setUserStatusLivechat(user._id, user.status !== 'offline' ? 'available' : 'not-available');
return user;
}

@ -1,4 +1,5 @@
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { roomTypes } from '../../utils';
@ -9,6 +10,7 @@ import { LivechatAgentActivityMonitor } from './statistics/LivechatAgentActivity
import { businessHourManager } from './business-hour';
import { createDefaultBusinessHourIfNotExists } from './business-hour/Helper';
import { hasPermission } from '../../authorization/server';
import { Livechat } from './lib/Livechat';
import './roomAccessValidator.internalService';
@ -54,4 +56,6 @@ Meteor.startup(async () => {
}
return businessHourManager.stopManager();
});
Accounts.onLogout(({ user }) => user?.roles?.includes('livechat-agent') && Livechat.setUserStatusLivechat(user._id, 'not-available'));
});

@ -247,6 +247,20 @@ export class UsersRaw extends BaseRaw {
return result.value;
}
setLivechatStatus(userId, status) { // TODO: Create class Agent
const query = {
_id: userId,
};
const update = {
$set: {
statusLivechat: status,
},
};
return this.update(query, update);
}
async getAgentAndAmountOngoingChats(userId) {
const aggregate = [
{ $match: { _id: userId, status: { $exists: true, $ne: 'offline' }, statusLivechat: 'available', roles: 'livechat-agent' } },
@ -605,6 +619,24 @@ export class UsersRaw extends BaseRaw {
return this.update(query, update, { multi: true });
}
setLivechatStatusActiveBasedOnBusinessHours(userId) {
const query = {
_id: userId,
openBusinessHours: {
$exists: true,
$not: { $size: 0 },
},
};
const update = {
$set: {
statusLivechat: 'available',
},
};
return this.update(query, update);
}
async isAgentWithinBusinessHours(agentId) {
return await this.find({
_id: agentId,

@ -57,7 +57,9 @@ export const AgentInfo = memo(function AgentInfo({ uid, children, ...props }) {
{statusLivechat && (
<>
<UserInfo.Label>{t('Livechat_status')}</UserInfo.Label>
<UserInfo.Info>{t(statusLivechat)}</UserInfo.Info>
<UserInfo.Info>
{t(statusLivechat === 'available' ? 'Available' : 'Not_Available')}
</UserInfo.Info>
</>
)}

Loading…
Cancel
Save