Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Verification check filter for Omnichannel rooms #30420

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
3 changes: 2 additions & 1 deletion apps/meteor/app/livechat/imports/server/rest/rooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ API.v1.addRoute(
async get() {
const { offset, count } = await getPaginationItems(this.queryParams);
const { sort, fields } = await this.parseJsonQuery();
const { agents, departmentId, open, tags, roomName, onhold } = this.queryParams;
const { agents, departmentId, open, tags, roomName, onhold, verificationStatus } = this.queryParams;
const { createdAt, customFields, closedAt } = this.queryParams;

const createdAtParam = validateDateParams('createdAt', createdAt);
Expand Down Expand Up @@ -63,6 +63,7 @@ API.v1.addRoute(
agents,
roomName,
departmentId,
verificationStatus,
...(isBoolean(open) && { open: open === 'true' }),
createdAt: createdAtParam,
closedAt: closedAtParam,
Expand Down
3 changes: 3 additions & 0 deletions apps/meteor/app/livechat/server/api/lib/rooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export async function findRooms({
agents,
roomName,
departmentId,
verificationStatus,
open,
createdAt,
closedAt,
Expand All @@ -19,6 +20,7 @@ export async function findRooms({
agents?: Array<string>;
roomName?: string;
departmentId?: string;
verificationStatus?: IOmnichannelRoom['verificationStatus'];
open?: boolean;
createdAt?: {
start?: string | undefined;
Expand All @@ -42,6 +44,7 @@ export async function findRooms({
createdAt,
closedAt,
tags,
verificationStatus,
customFields,
onhold: ['t', 'true', '1'].includes(`${onhold}`),
options: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { RoomVerificationState } from '@rocket.chat/core-typings';
import { Pagination } from '@rocket.chat/fuselage';
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import type { GETLivechatRoomsParams } from '@rocket.chat/rest-typings';
Expand Down Expand Up @@ -37,6 +38,7 @@ type DebouncedParams = {
department: string;
status: string;
from: string;
verificationStatus: RoomVerificationState;
to: string;
tags: any[];
};
Expand All @@ -47,6 +49,7 @@ type CurrentChatQuery = {
roomName?: string;
departmentId?: string;
open?: boolean;
verificationStatus?: RoomVerificationState;
createdAt?: string;
closedAt?: string;
tags?: string[];
Expand All @@ -67,7 +70,7 @@ type useQueryType = (
const sortDir = (sortDir: 'asc' | 'desc'): 1 | -1 => (sortDir === 'asc' ? 1 : -1);

const currentChatQuery: useQueryType = (
{ guest, servedBy, department, status, from, to, tags },
{ guest, servedBy, department, status, from, to, tags, verificationStatus },
customFields,
[column, direction],
current,
Expand All @@ -93,6 +96,9 @@ const currentChatQuery: useQueryType = (
}),
});
}
if (verificationStatus !== RoomVerificationState.all) {
query.verificationStatus = verificationStatus;
}

if (status !== 'all') {
query.open = status === 'opened' || status === 'onhold';
Expand Down Expand Up @@ -120,10 +126,9 @@ const currentChatQuery: useQueryType = (
};

const CurrentChatsRoute = (): ReactElement => {
const { sortBy, sortDirection, setSort } = useSort<'fname' | 'departmentId' | 'servedBy' | 'priorityWeight' | 'ts' | 'lm' | 'open'>(
'ts',
'desc',
);
const { sortBy, sortDirection, setSort } = useSort<
'fname' | 'departmentId' | 'servedBy' | 'priorityWeight' | 'ts' | 'lm' | 'open' | 'verifcationStatus'
>('ts', 'desc');
const [customFields, setCustomFields] = useState<{ [key: string]: string }>();

const t = useTranslation();
Expand All @@ -142,6 +147,7 @@ const CurrentChatsRoute = (): ReactElement => {
guest: '',
fname: '',
servedBy: '',
verificationStatus: RoomVerificationState.all,
status: 'all',
department: '',
from: '',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { RoomVerificationState } from '@rocket.chat/core-typings';
import { TextInput, Box, Select, InputBox } from '@rocket.chat/fuselage';
import { useMutableCallback, useLocalStorage } from '@rocket.chat/fuselage-hooks';
import { useSetModal, useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts';
Expand Down Expand Up @@ -32,8 +33,15 @@ const FilterByText: FilterByTextType = ({ setFilter, reload, customFields, setCu
['onhold', t('On_Hold_Chats')],
];

const verificationStatusOptions: [RoomVerificationState, string][] = [
[RoomVerificationState.all, t('All')],
[RoomVerificationState.verified, t('Verified')],
[RoomVerificationState.unVerified, t('Unverified')],
];

const [guest, setGuest] = useLocalStorage('guest', '');
const [servedBy, setServedBy] = useLocalStorage('servedBy', 'all');
const [verificationStatus, setVerificationStatus] = useLocalStorage('verificationStatus', 'all');
const [status, setStatus] = useLocalStorage('status', 'all');
const [department, setDepartment] = useLocalStorage<string>('department', 'all');
const [from, setFrom] = useLocalStorage('from', '');
Expand All @@ -47,10 +55,12 @@ const FilterByText: FilterByTextType = ({ setFilter, reload, customFields, setCu
const handleFrom = useMutableCallback((e) => setFrom(e.target.value));
const handleTo = useMutableCallback((e) => setTo(e.target.value));
const handleTags = useMutableCallback((e) => setTags(e));
const handleVerificationStatus = useMutableCallback((e) => setVerificationStatus(e));

const reset = useMutableCallback(() => {
setGuest('');
setServedBy('all');
setVerificationStatus(RoomVerificationState.all);
setStatus('all');
setDepartment('all');
setFrom('');
Expand All @@ -76,12 +86,13 @@ const FilterByText: FilterByTextType = ({ setFilter, reload, customFields, setCu
servedBy,
status,
department: department && department !== 'all' ? department : '',
verificationStatus,
from: from && moment(new Date(from)).utc().format('YYYY-MM-DDTHH:mm:ss'),
to: to && moment(new Date(to)).utc().format('YYYY-MM-DDTHH:mm:ss'),
tags: tags.map((tag) => tag.label),
customFields,
}));
}, [setFilter, guest, servedBy, status, department, from, to, tags, customFields]);
}, [setFilter, guest, servedBy, status, department, from, to, tags, customFields, verificationStatus]);

const handleClearFilters = useMutableCallback(() => {
reset();
Expand Down Expand Up @@ -140,11 +151,21 @@ const FilterByText: FilterByTextType = ({ setFilter, reload, customFields, setCu
hasCustomFields={hasCustomFields}
/>
</Box>
<Box display='flex' marginBlockStart={8} flexGrow={1} flexDirection='column'>
<Box display='flex' marginBlockStart={8} flexGrow={1} flexDirection='row'>
<Box display='flex' mie={8} flexGrow={1} flexDirection='column'>
<Label mb={4}>{t('Department')}</Label>
<AutoCompleteDepartment haveAll showArchived value={department} onChange={handleDepartment} onlyMyDepartments />
</Box>
<Box display='flex' mie={8} flexGrow={1} flexDirection='column'>
<Label mb={4}>{t('Verification_Check')}</Label>
<Select
options={verificationStatusOptions}
value={verificationStatus}
onChange={handleVerificationStatus}
placeholder={t('Verification_Check')}
data-qa='chat-verification-state'
/>
</Box>
</Box>
{EETagsComponent && (
<Box display='flex' flexDirection='row' marginBlockStart={8} {...props}>
Expand Down
2 changes: 2 additions & 0 deletions apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -5238,6 +5238,7 @@
"Unread_Tray_Icon_Alert": "Unread Tray Icon Alert",
"Unstar_Message": "Remove Star",
"Unmute_microphone": "Unmute Microphone",
"Unverified": "Unverified",
"Update": "Update",
"Update_EnableChecker": "Enable the Update Checker",
"Update_EnableChecker_Description": "Checks automatically for new updates / important messages from the Rocket.Chat developers and receives notifications when available. The notification appears once per new version as a clickable banner and as a message from the Rocket.Cat bot, both visible only for administrators.",
Expand Down Expand Up @@ -5413,6 +5414,7 @@
"Value_users": "{{value}} users",
"Verification": "Verification",
"Verification_Bot":"Enter the username for assigning the verification bot.",
"Verification_Check":"Verification Check",
"Verification_Description": "You may use the following placeholders: \n - `[Verification_Url]` for the verification URL. \n - `[name]`, `[fname]`, `[lname]` for the user's full name, first name or last name, respectively. \n - `[email]` for the user's email. \n - `[Site_Name]` and `[Site_URL]` for the Application Name and URL respectively. ",
"Verification_Email": "Click <a href=\"[Verification_Url]\">here</a> to verify your email address.",
"Verification_email_body": "Please, click on the button below to confirm your email address.",
Expand Down
3 changes: 3 additions & 0 deletions apps/meteor/server/models/raw/LivechatRooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,7 @@ export class LivechatRoomsRaw extends BaseRaw<IOmnichannelRoom> implements ILive
createdAt,
closedAt,
tags,
verificationStatus,
customFields,
visitorId,
roomIds,
Expand All @@ -1217,6 +1218,7 @@ export class LivechatRoomsRaw extends BaseRaw<IOmnichannelRoom> implements ILive
createdAt?: { start?: Date; end?: Date };
closedAt?: { start?: Date; end?: Date };
tags?: string[];
verificationStatus?: IOmnichannelRoom['verificationStatus'];
customFields?: Record<string, string>;
visitorId?: string;
roomIds?: string[];
Expand All @@ -1235,6 +1237,7 @@ export class LivechatRoomsRaw extends BaseRaw<IOmnichannelRoom> implements ILive
...(open !== undefined && { open: { $exists: open }, onHold: { $ne: true } }),
...(served !== undefined && { servedBy: { $exists: served } }),
...(visitorId && visitorId !== 'undefined' && { 'v._id': visitorId }),
...(verificationStatus && { verificationStatus }),
};

if (createdAt) {
Expand Down
1 change: 1 addition & 0 deletions packages/core-typings/src/IRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ export enum RoomVerificationState {
unVerified = 'unVerified',
verified = 'verified',
verifiedFalse = 'verifiedFalse',
all = 'all',
}

export interface IOmnichannelGenericRoom extends Omit<IRoom, 'default' | 'featured' | 'broadcast' | ''> {
Expand Down
1 change: 1 addition & 0 deletions packages/model-typings/src/models/ILivechatRoomsModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export interface ILivechatRoomsModel extends IBaseModel<IOmnichannelRoom> {
createdAt: any;
closedAt: any;
tags: any;
verificationStatus?: RoomVerificationState;
customFields: any;
visitorId?: any;
roomIds?: any;
Expand Down
8 changes: 7 additions & 1 deletion packages/rest-typings/src/v1/omnichannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import type {
ILivechatTriggerCondition,
ILivechatTriggerAction,
} from '@rocket.chat/core-typings';
import { ILivechatAgentStatus } from '@rocket.chat/core-typings';
import { RoomVerificationState, ILivechatAgentStatus } from '@rocket.chat/core-typings';
import Ajv from 'ajv';
import type { WithId } from 'mongodb';

Expand Down Expand Up @@ -2534,6 +2534,7 @@ export type GETLivechatRoomsParams = PaginatedRequest<{
customFields?: string;
closedAt?: string;
agents?: string[];
verificationStatus?: IOmnichannelRoom['verificationStatus'];
roomName?: string;
departmentId?: string;
open?: string | boolean;
Expand Down Expand Up @@ -2587,6 +2588,11 @@ const GETLivechatRoomsParamsSchema = {
type: 'string',
nullable: true,
},
verificationStatus: {
type: 'string',
enum: Object.values(RoomVerificationState),
nullable: true,
},
open: {
type: ['string', 'boolean'],
nullable: true,
Expand Down