Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/definitions/IRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface IRoom {
token?: string;
status: 'online' | 'busy' | 'away' | 'offline';
};
status?: string;
servedBy?: IServedBy;
departmentId?: string;
livechatData?: any;
Expand Down
10 changes: 5 additions & 5 deletions app/definitions/ISubscription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ export enum SubscriptionType {
}

export interface IVisitor {
_id: string;
username: string;
token: string;
status: string;
lastMessageTs: Date;
_id?: string;
token?: string;
status: 'online' | 'busy' | 'away' | 'offline';
username?: string;
lastMessageTs?: Date;
}

export interface ISubscription {
Expand Down
7 changes: 5 additions & 2 deletions app/definitions/redux/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// ACTIONS
import { TActionInquiry } from '../../ee/omnichannel/actions/inquiry';
import { TActionActiveUsers } from '../../actions/activeUsers';
import { TActionApp } from '../../actions/app';
import { TActionCreateChannel } from '../../actions/createChannel';
Expand Down Expand Up @@ -26,6 +27,7 @@ import { ISelectedUsers } from '../../reducers/selectedUsers';
import { IServer } from '../../reducers/server';
import { ISettings } from '../../reducers/settings';
import { IShare } from '../../reducers/share';
import { IInquiry } from '../../ee/omnichannel/reducers/inquiry';

export interface IApplicationState {
settings: ISettings;
Expand All @@ -44,7 +46,7 @@ export interface IApplicationState {
usersTyping: any;
inviteLinks: IInviteLinks;
createDiscussion: ICreateDiscussion;
inquiry: any;
inquiry: IInquiry;
enterpriseModules: any;
encryption: IEncryption;
permissions: any;
Expand All @@ -64,4 +66,5 @@ export type TApplicationActions = TActionActiveUsers &
TActionCreateChannel &
TActionsShare &
TActionServer &
TActionApp;
TActionApp &
TActionInquiry;
55 changes: 0 additions & 55 deletions app/ee/omnichannel/actions/inquiry.js

This file was deleted.

84 changes: 84 additions & 0 deletions app/ee/omnichannel/actions/inquiry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { Action } from 'redux';

import { IRoom } from '../../../definitions';
import { INQUIRY } from '../../../actions/actionsTypes';

interface IInquirySetEnabled extends Action {
enabled: boolean;
}

interface IInquiryQueueAddAndUpdate extends Action {
inquiry: IRoom;
}

interface IInquirySuccess extends Action {
inquiries: IRoom[];
}

interface IInquiryQueueRemove extends Action {
inquiryId: string;
}

interface IInquiryFailure extends Action {
error: unknown;
}

export type TActionInquiry = IInquirySetEnabled &
IInquiryQueueAddAndUpdate &
IInquirySuccess &
IInquiryQueueRemove &
IInquiryFailure;

export function inquirySetEnabled(enabled: boolean): IInquirySetEnabled {
return {
type: INQUIRY.SET_ENABLED,
enabled
};
}

export function inquiryReset(): Action {
return {
type: INQUIRY.RESET
};
}

export function inquiryQueueAdd(inquiry: IRoom): IInquiryQueueAddAndUpdate {
return {
type: INQUIRY.QUEUE_ADD,
inquiry
};
}

export function inquiryQueueUpdate(inquiry: IRoom): IInquiryQueueAddAndUpdate {
return {
type: INQUIRY.QUEUE_UPDATE,
inquiry
};
}

export function inquiryQueueRemove(inquiryId: string): IInquiryQueueRemove {
return {
type: INQUIRY.QUEUE_REMOVE,
inquiryId
};
}

export function inquiryRequest(): Action {
return {
type: INQUIRY.REQUEST
};
}

export function inquirySuccess(inquiries: IRoom[]): IInquirySuccess {
return {
type: INQUIRY.SUCCESS,
inquiries
};
}

export function inquiryFailure(error: unknown): IInquiryFailure {
return {
type: INQUIRY.FAILURE,
error
};
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
import React, { memo, useEffect, useState } from 'react';
import { Switch, View } from 'react-native';
import PropTypes from 'prop-types';

import * as List from '../../../containers/List';
import styles from '../../../views/RoomsListView/styles';
import { SWITCH_TRACK_COLOR, themes } from '../../../constants/colors';
import { withTheme } from '../../../theme';
import { useTheme } from '../../../theme';
import UnreadBadge from '../../../presentation/UnreadBadge';
import RocketChat from '../../../lib/rocketchat';
import { changeLivechatStatus, isOmnichannelStatusAvailable } from '../lib';
import { IUser } from '../../../definitions/IUser';

const OmnichannelStatus = memo(({ searching, goQueue, theme, queueSize, inquiryEnabled, user }) => {
if (searching > 0 || !(RocketChat.isOmnichannelModuleAvailable() && user?.roles?.includes('livechat-agent'))) {
interface IOmnichannelStatus {
searching: boolean;
goQueue: () => void;
queueSize: number;
inquiryEnabled: boolean;
user: IUser;
}

const OmnichannelStatus = memo(({ searching, goQueue, queueSize, inquiryEnabled, user }: IOmnichannelStatus) => {
if (!!searching || !(RocketChat.isOmnichannelModuleAvailable() && user?.roles?.includes('livechat-agent'))) {
Comment thread
reinaldonetof marked this conversation as resolved.
Outdated
return null;
}
const { theme } = useTheme();
const [status, setStatus] = useState(isOmnichannelStatusAvailable(user));

useEffect(() => {
Expand Down Expand Up @@ -48,16 +57,4 @@ const OmnichannelStatus = memo(({ searching, goQueue, theme, queueSize, inquiryE
);
});

OmnichannelStatus.propTypes = {
searching: PropTypes.bool,
goQueue: PropTypes.func,
queueSize: PropTypes.number,
inquiryEnabled: PropTypes.bool,
theme: PropTypes.string,
user: PropTypes.shape({
roles: PropTypes.array,
statusLivechat: PropTypes.string
})
};

export default withTheme(OmnichannelStatus);
export default OmnichannelStatus;
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import RocketChat from '../../../lib/rocketchat';
import sdk from '../../../lib/rocketchat/services/sdk';
import { IUser } from '../../../definitions';
import EventEmitter from '../../../utils/events';
import subscribeInquiry from './subscriptions/inquiry';

export const isOmnichannelStatusAvailable = user => user?.statusLivechat === 'available';
export const isOmnichannelStatusAvailable = (user: IUser): boolean => user?.statusLivechat === 'available';

// RC 0.26.0
export const changeLivechatStatus = () => RocketChat.methodCallWrapper('livechat:changeLivechatStatus');
export const changeLivechatStatus = () => sdk.methodCallWrapper('livechat:changeLivechatStatus');

// RC 2.4.0
export const getInquiriesQueued = () => RocketChat.sdk.get('livechat/inquiries.queued');
// @ts-ignore
export const getInquiriesQueued = () => sdk.get('livechat/inquiries.queued');

// this inquiry is added to the db by the subscriptions stream
// and will be removed by the queue stream
// RC 2.4.0
export const takeInquiry = inquiryId => RocketChat.methodCallWrapper('livechat:takeInquiry', inquiryId);
export const takeInquiry = (inquiryId: string) => sdk.methodCallWrapper('livechat:takeInquiry', inquiryId);

class Omnichannel {
private inquirySub: { stop: () => void } | null;
constructor() {
this.inquirySub = null;
EventEmitter.addEventListener('INQUIRY_SUBSCRIBE', this.subscribeInquiry);
Expand All @@ -36,5 +39,5 @@ class Omnichannel {
};
}

// eslint-disable-next-line no-unused-vars
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const omnichannel = new Omnichannel();
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,28 @@ import log from '../../../../utils/log';
import { store } from '../../../../lib/auxStore';
import RocketChat from '../../../../lib/rocketchat';
import { inquiryQueueAdd, inquiryQueueRemove, inquiryQueueUpdate, inquiryRequest } from '../../actions/inquiry';
import sdk from '../../../../lib/rocketchat/services/sdk';
import { ILivechatDepartment } from '../../../../definitions/ILivechatDepartment';
import { IRoom } from '../../../../definitions';

const removeListener = listener => listener.stop();
interface IArgsQueueOmnichannel extends IRoom {
type: string;
}

interface IDdpMessage {
msg: string;
collection: string;
id: string;
fields: {
eventName: string;
args: IArgsQueueOmnichannel[];
};
}

const removeListener = (listener: any) => listener.stop();

let connectedListener;
let queueListener;
let connectedListener: any;
let queueListener: any;

const streamTopic = 'stream-livechat-inquiry-queue-observer';

Expand All @@ -15,7 +32,7 @@ export default function subscribeInquiry() {
store.dispatch(inquiryRequest());
};

const handleQueueMessageReceived = ddpMessage => {
const handleQueueMessageReceived = (ddpMessage: IDdpMessage) => {
const [{ type, ...sub }] = ddpMessage.fields.args;

// added can be ignored, since it is handled by 'changed' event
Expand All @@ -26,7 +43,9 @@ export default function subscribeInquiry() {
// if the sub isn't on the queue anymore
if (sub.status !== 'queued') {
// remove it from the queue
store.dispatch(inquiryQueueRemove(sub._id));
if (sub._id) {
store.dispatch(inquiryQueueRemove(sub._id));
}
return;
}

Expand All @@ -53,23 +72,23 @@ export default function subscribeInquiry() {
}
};

connectedListener = RocketChat.onStreamData('connected', handleConnection);
queueListener = RocketChat.onStreamData(streamTopic, handleQueueMessageReceived);
connectedListener = sdk.onStreamData('connected', handleConnection);
queueListener = sdk.onStreamData(streamTopic, handleQueueMessageReceived);

try {
const { user } = store.getState().login;
RocketChat.getAgentDepartments(user.id).then(result => {
RocketChat.getAgentDepartments(user.id).then((result: { success: boolean; departments: ILivechatDepartment[] }) => {
Comment thread
reinaldonetof marked this conversation as resolved.
if (result.success) {
const { departments } = result;

if (!departments.length || RocketChat.hasRole('livechat-manager')) {
RocketChat.subscribe(streamTopic, 'public').catch(e => console.log(e));
sdk.subscribe(streamTopic, 'public').catch((e: unknown) => console.log(e));
}

const departmentIds = departments.map(({ departmentId }) => departmentId);
departmentIds.forEach(departmentId => {
// subscribe to all departments of the agent
RocketChat.subscribe(streamTopic, `department/${departmentId}`).catch(e => console.log(e));
sdk.subscribe(streamTopic, `department/${departmentId}`).catch((e: unknown) => console.log(e));
});
}
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { IRoom, TApplicationActions } from '../../../definitions';
import { INQUIRY } from '../../../actions/actionsTypes';

const initialState = {
export interface IInquiry {
Comment thread
reinaldonetof marked this conversation as resolved.
enabled: boolean;
queued: IRoom[];
error: any;
}

const initialState: IInquiry = {
enabled: false,
queued: [],
error: {}
};

export default function inquiry(state = initialState, action) {
export default function inquiry(state = initialState, action: TApplicationActions): IInquiry {
switch (action.type) {
case INQUIRY.SUCCESS:
return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { createSelector } from 'reselect';

const getInquiryQueue = state => state.inquiry.queued;
import { IApplicationState } from '../../../definitions';

const getInquiryQueue = (state: IApplicationState) => state.inquiry.queued;

export const getInquiryQueueSelector = createSelector([getInquiryQueue], queue => queue);
Loading