fix: "Discussions" filter is prioritized in admin "Rooms" page (#28426)

Co-authored-by: gabriellsh <40830821+gabriellsh@users.noreply.github.com>
Co-authored-by: matheusbsilva137 <matheus_barbosa137@hotmail.com>
Co-authored-by: Matheus Barbosa Silva <36537004+matheusbsilva137@users.noreply.github.com>
pull/29537/head
Heitor Tanoue 3 years ago committed by GitHub
parent 7967d465d4
commit 16dca466ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      .changeset/wet-tomatoes-happen.md
  2. 10
      apps/meteor/app/api/server/lib/rooms.ts
  3. 2
      apps/meteor/app/api/server/v1/rooms.ts
  4. 14
      apps/meteor/client/views/admin/rooms/FilterByTypeAndText.tsx
  5. 2
      apps/meteor/client/views/admin/rooms/RoomsTable.tsx
  6. 95
      apps/meteor/server/models/raw/Rooms.ts
  7. 82
      apps/meteor/tests/end-to-end/api/09-rooms.js
  8. 21
      packages/model-typings/src/models/IRoomsModel.ts

@ -0,0 +1,6 @@
---
"@rocket.chat/meteor": patch
"@rocket.chat/model-typings": patch
---
fix: "Discussions" filter is prioritized in admin "Rooms" page

@ -27,7 +27,6 @@ export async function findAdminRooms({
const name = filter?.trim();
const discussion = types?.includes('discussions');
const includeTeams = types?.includes('teams');
const showOnlyTeams = types.length === 1 && types.includes('teams');
const typesToRemove = ['discussions', 'teams'];
const showTypes = Array.isArray(types) ? types.filter((type): type is RoomType => !typesToRemove.includes(type)) : [];
const options: FindOptions<IRoom> = {
@ -36,14 +35,7 @@ export async function findAdminRooms({
limit: count,
};
let result;
if (name && showTypes.length) {
result = Rooms.findByNameOrFnameContainingAndTypes(name, showTypes, discussion, includeTeams, showOnlyTeams, options);
} else if (showTypes.length) {
result = Rooms.findByTypes(showTypes, discussion, includeTeams, showOnlyTeams, options);
} else {
result = Rooms.findByNameOrFnameContaining(name, discussion, includeTeams, showOnlyTeams, options);
}
const result = Rooms.findByNameOrFnameContainingAndTypes(name, showTypes, discussion, includeTeams, options);
const { cursor, totalCount } = result;

@ -398,7 +398,7 @@ API.v1.addRoute(
await findAdminRooms({
uid: this.userId,
filter: filter || '',
types: types || [],
types: (types && !Array.isArray(types) ? [types] : types) ?? [],
pagination: {
offset,
count,

@ -4,17 +4,17 @@ import { useTranslation } from '@rocket.chat/ui-contexts';
import type { ReactElement, Dispatch, SetStateAction } from 'react';
import React, { useCallback, useState, useEffect } from 'react';
const DEFAULT_TYPES = ['d', 'p', 'c', 'teams'];
const DEFAULT_TYPES = ['d', 'p', 'c', 'l', 'discussions', 'teams'];
const FilterByTypeAndText = ({ setFilter, ...props }: { setFilter?: Dispatch<SetStateAction<any>> }): ReactElement => {
const [text, setText] = useState('');
const [types, setTypes] = useState({
d: false,
c: false,
p: false,
l: false,
discussions: false,
teams: false,
d: true,
c: true,
p: true,
l: true,
discussions: true,
teams: true,
});
const t = useTranslation();

@ -29,7 +29,7 @@ type RoomFilters = {
text: string;
};
const DEFAULT_TYPES = ['d', 'p', 'c', 'teams'];
const DEFAULT_TYPES = ['d', 'p', 'c', 'l', 'discussions', 'teams'];
const roomTypeI18nMap = {
l: 'Omnichannel',

@ -164,26 +164,11 @@ export class RoomsRaw extends BaseRaw<IRoom> implements IRoomsModel {
types: Array<IRoom['t']>,
discussion = false,
teams = false,
showOnlyTeams = false,
options: FindOptions<IRoom> = {},
): FindPaginated<FindCursor<IRoom>> {
const nameRegex = new RegExp(escapeRegExp(name).trim(), 'i');
const onlyTeamsQuery: Filter<IRoom> = showOnlyTeams ? { teamMain: { $exists: true } } : {};
const teamCondition: Filter<IRoom> = teams
? {}
: {
teamMain: {
$exists: false,
},
};
const query: Filter<IRoom> = {
t: {
$in: types,
},
prid: { $exists: discussion },
const nameCondition: Filter<IRoom> = {
$or: [
{ name: nameRegex, federated: { $ne: true } },
{ fname: nameRegex },
@ -192,71 +177,27 @@ export class RoomsRaw extends BaseRaw<IRoom> implements IRoomsModel {
usernames: nameRegex,
},
],
...teamCondition,
...onlyTeamsQuery,
};
return this.findPaginated(query, options);
}
findByTypes(
types: Array<IRoom['t']>,
discussion = false,
teams = false,
onlyTeams = false,
options: FindOptions<IRoom> = {},
): FindPaginated<FindCursor<IRoom>> {
const teamCondition = teams
? {}
: {
teamMain: {
$exists: false,
},
};
const onlyTeamsCondition = onlyTeams ? { teamMain: { $exists: true } } : {};
const query: Filter<IRoom> = {
t: {
$in: types,
},
prid: { $exists: discussion },
...teamCondition,
...onlyTeamsCondition,
};
return this.findPaginated(query, options);
}
findByNameOrFnameContaining(
name: NonNullable<IRoom['name']>,
discussion = false,
teams = false,
onlyTeams = false,
options: FindOptions<IRoom> = {},
): FindPaginated<FindCursor<IRoom>> {
const nameRegex = new RegExp(escapeRegExp(name).trim(), 'i');
const teamCondition = teams
? {}
: {
teamMain: {
$exists: false,
},
};
const onlyTeamsCondition = onlyTeams ? { $and: [{ teamMain: { $exists: true } }, { teamMain: true }] } : {};
const query: Filter<IRoom> = {
prid: { $exists: discussion },
$or: [
{ name: nameRegex, federated: { $ne: true } },
{ fname: nameRegex },
{
t: 'd',
usernames: nameRegex,
},
$and: [
name ? nameCondition : {},
(types && types.length) || discussion || teams
? {
$or: [
{
t: {
$in: types,
},
},
...(discussion ? [{ prid: { $exists: true } }] : []),
...(teams ? [{ teamMain: { $exists: true } }] : []),
],
}
: {},
],
...teamCondition,
...onlyTeamsCondition,
...(!discussion ? { prid: { $exists: false } } : {}),
...(!teams ? { teamMain: { $exists: false } } : {}),
};
return this.findPaginated(query, options);

@ -1306,10 +1306,23 @@ describe('[Rooms]', function () {
const suffix = `test-${Date.now()}`;
const fnameRoom = `Ελληνικά-${suffix}`;
const nameRoom = `Ellinika-${suffix}`;
const discussionRoomName = `${nameRoom}-discussion`;
let testGroup;
before((done) => {
updateSetting('UI_Allow_room_names_with_special_chars', true).then(() => {
createRoom({ type: 'p', name: fnameRoom }).end(done);
createRoom({ type: 'p', name: fnameRoom }).end((err, res) => {
testGroup = res.body.group;
request
.post(api('rooms.createDiscussion'))
.set(credentials)
.send({
prid: testGroup._id,
t_name: discussionRoomName,
})
.end(done);
});
});
});
@ -1400,6 +1413,73 @@ describe('[Rooms]', function () {
.end(done);
});
});
it('should filter by only rooms types', (done) => {
request
.get(api('rooms.adminRooms'))
.set(credentials)
.query({
types: ['p'],
})
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('rooms').and.to.be.an('array');
expect(res.body.rooms).to.have.lengthOf.at.least(1);
expect(res.body.rooms[0].t).to.be.equal('p');
expect(res.body.rooms.find((room) => room.name === nameRoom)).to.exist;
expect(res.body.rooms.find((room) => room.name === discussionRoomName)).to.not.exist;
})
.end(done);
});
it('should filter by only name', (done) => {
request
.get(api('rooms.adminRooms'))
.set(credentials)
.query({
filter: nameRoom,
})
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('rooms').and.to.be.an('array');
expect(res.body.rooms).to.have.lengthOf(1);
expect(res.body.rooms[0].name).to.be.equal(nameRoom);
})
.end(done);
});
it('should filter by type and name at the same query', (done) => {
request
.get(api('rooms.adminRooms'))
.set(credentials)
.query({
filter: nameRoom,
types: ['p'],
})
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('rooms').and.to.be.an('array');
expect(res.body.rooms).to.have.lengthOf(1);
expect(res.body.rooms[0].name).to.be.equal(nameRoom);
})
.end(done);
});
it('should return an empty array when filter by wrong type and correct room name', (done) => {
request
.get(api('rooms.adminRooms'))
.set(credentials)
.query({
filter: nameRoom,
types: ['c'],
})
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('rooms').and.to.be.an('array');
expect(res.body.rooms).to.have.lengthOf(0);
})
.end(done);
});
});
describe('update group dms name', () => {

@ -32,25 +32,8 @@ export interface IRoomsModel extends IBaseModel<IRoom> {
findByNameOrFnameContainingAndTypes(
name: NonNullable<IRoom['name']>,
types: Array<IRoom['t']>,
discussion: boolean,
teams: boolean,
showOnlyTeams: boolean,
options?: FindOptions<IRoom>,
): FindPaginated<FindCursor<IRoom>>;
findByTypes(
types: Array<IRoom['t']>,
discussion: boolean,
teams: boolean,
onlyTeams: boolean,
options?: FindOptions<IRoom>,
): FindPaginated<FindCursor<IRoom>>;
findByNameOrFnameContaining(
name: NonNullable<IRoom['name']>,
discussion: boolean,
teams: boolean,
onlyTeams: boolean,
discussion?: boolean,
teams?: boolean,
options?: FindOptions<IRoom>,
): FindPaginated<FindCursor<IRoom>>;

Loading…
Cancel
Save