Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 6 additions & 0 deletions client/contexts/ServerContext/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import { ListEndpoint as EmojiCustomListEndpoint } from './endpoints/v1/emoji-cu
import { FilesEndpoint as GroupsFilesEndpoint } from './endpoints/v1/groups/files';
import { FilesEndpoint as ImFilesEndpoint } from './endpoints/v1/im/files';
import { AppearanceEndpoint as LivechatAppearanceEndpoint } from './endpoints/v1/livechat/appearance';
import { LivechatDepartment } from './endpoints/v1/livechat/department';
import { LivechatDepartmentsByUnit } from './endpoints/v1/livechat/departmentsByUnit';
import { LivechatMonitorsList } from './endpoints/v1/livechat/monitorsList';
import { LivechatRoomOnHoldEndpoint } from './endpoints/v1/livechat/onHold';
import { LivechatVisitorInfoEndpoint } from './endpoints/v1/livechat/visitorInfo';
import { AutocompleteAvailableForTeamsEndpoint as RoomsAutocompleteTeamsEndpoint } from './endpoints/v1/rooms/autocompleteAvailableForTeams';
Expand Down Expand Up @@ -40,6 +43,9 @@ export type ServerEndpoints = {
'teams.addRooms': TeamsAddRoomsEndpoint;
'livechat/visitors.info': LivechatVisitorInfoEndpoint;
'livechat/room.onHold': LivechatRoomOnHoldEndpoint;
'livechat/monitors.list': LivechatMonitorsList;
'livechat/department': LivechatDepartment;
'livechat/departments.by-unit/': LivechatDepartmentsByUnit;
};

export type ServerEndpointPath = keyof ServerEndpoints;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export type LivechatDepartment = {
GET: (params: {
query: string;
}) => {
statuses: unknown[];
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ILivechatDepartment } from '../../../../../../definition/ILivechatDepartment';
import { ObjectFromApi } from '../../../../../../definition/ObjectFromApi';

export type LivechatDepartmentsByUnit = {
GET: (params: {
text: string;
offset: number;
count: number;
}) => {
departments: ObjectFromApi<ILivechatDepartment>[];
total: number;
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ILivechatMonitor } from '../../../../../../definition/ILivechatMonitor';
import { ObjectFromApi } from '../../../../../../definition/ObjectFromApi';

export type LivechatMonitorsList = {
GET: (params: {
text: string;
offset: number;
count: number;
}) => {
monitors: ObjectFromApi<ILivechatMonitor>[];
total: number;
};
};
63 changes: 63 additions & 0 deletions client/views/hooks/useDepartmentsList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { useCallback, useState } from 'react';

import { ILivechatDepartmentRecord } from '../../../definition/ILivechatDepartmentRecord';
import { useEndpoint } from '../../contexts/ServerContext';
import { useScrollableRecordList } from '../../hooks/lists/useScrollableRecordList';
import { useComponentDidUpdate } from '../../hooks/useComponentDidUpdate';
import { RecordList } from '../../lib/lists/RecordList';

type DepartmentsListOptions = {
unitId: string;
filter: string;
};

export const useDepartmentsList = (
options: DepartmentsListOptions,
): {
itemsList: RecordList<ILivechatDepartmentRecord>;
initialItemCount: number;
reload: () => void;
loadMoreItems: (start: number, end: number) => void;
} => {
const [itemsList, setItemsList] = useState(() => new RecordList<ILivechatDepartmentRecord>());
const reload = useCallback(() => setItemsList(new RecordList<ILivechatDepartmentRecord>()), []);
const endpoint = `livechat/departments.available-by-unit/${
options.unitId || 'none'
}` as 'livechat/departments.by-unit/';

const getDepartments = useEndpoint('GET', endpoint);

useComponentDidUpdate(() => {
options && reload();
}, [options, reload]);

const fetchData = useCallback(
async (start, end) => {
const { departments, total } = await getDepartments({
text: options.filter,
offset: start,
count: end + start,
});

return {
items: departments.map((department: any) => {
department._updatedAt = new Date(department._updatedAt);
department.label = department.name;
department.value = { value: department._id, label: department.name };
return department;
}),
itemCount: total,
};
},
[getDepartments, options.filter],
);

const { loadMoreItems, initialItemCount } = useScrollableRecordList(itemsList, fetchData, 25);

return {
reload,
itemsList,
loadMoreItems,
initialItemCount,
};
};
60 changes: 60 additions & 0 deletions client/views/hooks/useMonitorsList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useCallback, useState } from 'react';

import { ILivechatMonitorRecord } from '../../../definition/ILivechatMonitorRecord';
import { useEndpoint } from '../../contexts/ServerContext';
import { useScrollableRecordList } from '../../hooks/lists/useScrollableRecordList';
import { useComponentDidUpdate } from '../../hooks/useComponentDidUpdate';
import { RecordList } from '../../lib/lists/RecordList';

type MonitorsListOptions = {
filter: string;
};

export const useMonitorsList = (
options: MonitorsListOptions,
): {
itemsList: RecordList<ILivechatMonitorRecord>;
initialItemCount: number;
reload: () => void;
loadMoreItems: (start: number, end: number) => void;
} => {
const [itemsList, setItemsList] = useState(() => new RecordList<ILivechatMonitorRecord>());
const reload = useCallback(() => setItemsList(new RecordList<ILivechatMonitorRecord>()), []);

const endpoint = 'livechat/monitors.list';

const getMonitors = useEndpoint('GET', endpoint);

useComponentDidUpdate(() => {
options && reload();
}, [options, reload]);

const fetchData = useCallback(
async (start, end) => {
const { monitors, total } = await getMonitors({
text: options.filter,
offset: start,
count: end + start,
});

return {
items: monitors.map((members: any) => {
members._updatedAt = new Date(members._updatedAt);
members.label = members.username;
members.value = { value: members._id, label: members.username };
return members;
}),
itemCount: total,
};
},
[getMonitors, options.filter],
);

const { loadMoreItems, initialItemCount } = useScrollableRecordList(itemsList, fetchData, 25);
return {
reload,
itemsList,
loadMoreItems,
initialItemCount,
};
};
17 changes: 17 additions & 0 deletions definition/ILivechatDepartmentRecord.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { IRocketChatRecord } from './IRocketChatRecord';


export interface ILivechatDepartmentRecord extends IRocketChatRecord {
_id: string;
name: string;
enabled: boolean;
description: string;
showOnRegistration: boolean;
showOnOfflineForm: boolean;
requestTagBeforeClosingChat: boolean;
email: string;
chatClosingTags: string[];
offlineMessageChannelName: string;
numAgents: number;
businessHourId?: string;
}
8 changes: 8 additions & 0 deletions definition/ILivechatMonitor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface ILivechatMonitor {
_id: string;
name: string;
enabled: boolean;
numMonitors: number;
type: string;
visibility: string;
}
11 changes: 11 additions & 0 deletions definition/ILivechatMonitorRecord.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { IRocketChatRecord } from './IRocketChatRecord';


export interface ILivechatMonitorRecord extends IRocketChatRecord {
_id: string;
name: string;
enabled: boolean;
numMonitors: number;
type: string;
visibility: string;
}
44 changes: 44 additions & 0 deletions ee/app/livechat-enterprise/server/api/departments.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import {
findPercentageOfAbandonedRooms,
findAllAverageOfChatDurationTime,
} from '../../../../../app/livechat/server/lib/analytics/departments';
import {
findAllDepartmentsAvailable,
findAllDepartmentsByUnit,
} from '../lib/Department';

API.v1.addRoute('livechat/analytics/departments/amount-of-chats', { authRequired: true }, {
get() {
Expand Down Expand Up @@ -318,3 +322,43 @@ API.v1.addRoute('livechat/analytics/departments/percentage-abandoned-chats', { a
});
},
});

API.v1.addRoute('livechat/departments.available-by-unit/:unitId', { authRequired: true }, {
get() {
check(this.urlParams, {
unitId: Match.Maybe(String),
});
const { offset, count } = this.getPaginationItems();
const { unitId } = this.urlParams;
const { text } = this.queryParams;


const { departments, total } = Promise.await(findAllDepartmentsAvailable(unitId, offset, count, text));

return API.v1.success({
departments,
count: departments.length,
offset,
total,
});
},
});

API.v1.addRoute('livechat/departments.by-unit/:unitId', { authRequired: true }, {
get() {
check(this.urlParams, {
unitId: String,
});
const { offset, count } = this.getPaginationItems();
const { unitId } = this.urlParams;

const { departments, total } = Promise.await(findAllDepartmentsByUnit(unitId, offset, count));

return API.v1.success({
departments,
count: departments.length,
offset,
total,
});
},
});
32 changes: 32 additions & 0 deletions ee/app/livechat-enterprise/server/lib/Department.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { escapeRegExp } from '@rocket.chat/string-helpers';

import {
LivechatDepartment,
} from '../../../../../app/models/server/raw';

export const findAllDepartmentsAvailable = async (unitId, offset, count, text) => {
const filterReg = new RegExp(escapeRegExp(text), 'i');

const cursor = LivechatDepartment.find({
$or: [{ ancestors: { $in: [unitId] } }, { ancestors: { $exists: false } }],
...text && { name: filterReg },

}, { limit: count, offset });

const departments = await cursor.toArray();
const total = await cursor.count();
const departmentsFiltered = departments.filter((department) => !department.ancestors?.length);

return { departments: departmentsFiltered, total };
};

export const findAllDepartmentsByUnit = async (unitId, offset, count) => {
const cursor = LivechatDepartment.find({
ancestors: { $in: [unitId] },
}, { limit: count, offset });

const total = await cursor.count();
const departments = await cursor.toArray();

return { departments, total };
};
Loading