diff --git a/app/models/server/models/Rooms.js b/app/models/server/models/Rooms.js
index fdfa62320099..8455d1a5c27f 100644
--- a/app/models/server/models/Rooms.js
+++ b/app/models/server/models/Rooms.js
@@ -552,38 +552,40 @@ export class Rooms extends Base {
return this._db.find(query, options);
}
- findByNameOrFNameAndTypeIncludingTeamRooms(name, type, teamIds, options) {
+ findByNameOrFNameAndRoomIdsIncludingTeamRooms(text, teamIds, roomIds, options) {
+ const searchTerm = text && new RegExp(text, 'i');
+
const query = {
- t: type,
- teamMain: {
- $exists: false,
- },
$and: [
+ { teamMain: { $exists: false } },
+ { prid: { $exists: false } },
{
$or: [
{
- teamId: {
- $exists: false,
- },
+ t: 'c',
+ teamId: { $exists: false },
},
{
- teamId: {
- $in: teamIds,
- },
+ t: 'c',
+ teamId: { $in: teamIds },
},
+ ...roomIds?.length > 0 ? [{
+ _id: {
+ $in: roomIds,
+ },
+ }] : [],
],
},
- {
+ ...searchTerm ? [{
$or: [{
- name,
+ name: searchTerm,
}, {
- fname: name,
+ fname: searchTerm,
}],
- },
+ }] : [],
],
};
- // do not use cache
return this._db.find(query, options);
}
@@ -603,7 +605,7 @@ export class Rooms extends Base {
};
if (text) {
- const regex = new RegExp(s.trim(escapeRegExp(text)), 'i');
+ const regex = new RegExp(text, 'i');
query.$and.push({
$or: [{
diff --git a/client/views/directory/ChannelsTable.js b/client/views/directory/ChannelsTable.js
index 9c817ae378cf..842a880acb14 100644
--- a/client/views/directory/ChannelsTable.js
+++ b/client/views/directory/ChannelsTable.js
@@ -101,16 +101,17 @@ function ChannelsTable() {
);
const channelRoute = useRoute('channel');
+ const groupsRoute = useRoute('group');
const { value: data = { result: [] } } = useEndpointData('directory', query);
const onClick = useMemo(
- () => (name) => (e) => {
+ () => (name, type) => (e) => {
if (e.type === 'click' || e.key === 'Enter') {
- channelRoute.push({ name });
+ type === 'c' ? channelRoute.push({ name }) : groupsRoute.push({ name });
}
},
- [channelRoute],
+ [channelRoute, groupsRoute],
);
const formatDate = useFormatDate();
@@ -122,8 +123,8 @@ function ChannelsTable() {
return (
{
+const getChannelsAndGroups = (user, canViewAnon, searchTerm, sort, pagination) => {
if ((!user && !canViewAnon) || (user && !hasPermission(user._id, 'view-c-room'))) {
return;
}
const teams = Promise.await(Team.getAllPublicTeams());
- const teamIds = teams.map(({ _id }) => _id);
+ const publicTeamIds = teams.map(({ _id }) => _id);
- const result = Rooms.findByNameOrFNameAndTypeIncludingTeamRooms(searchTerm, 'c', teamIds, {
+ const userTeamsIds = Promise.await(Team.listTeamsBySubscriberUserId(user._id, { projection: { teamId: 1 } }))?.map(({ teamId }) => teamId) || [];
+ const userRooms = user.__rooms;
+
+ const cursor = Rooms.findByNameOrFNameAndRoomIdsIncludingTeamRooms(searchTerm, [...userTeamsIds, ...publicTeamIds], userRooms, {
...pagination,
sort: {
featured: -1,
@@ -74,11 +77,15 @@ const getChannels = (user, canViewAnon, searchTerm, sort, pagination) => {
teamId: 1,
},
});
+ const total = cursor.count(); // count ignores the `skip` and `limit` options
+ const result = cursor.fetch();
- const total = result.count(); // count ignores the `skip` and `limit` options
- const results = result.fetch().map((room) => {
+ const teamIds = result.filter(({ teamId }) => teamId).map(({ teamId }) => teamId);
+ const teamsMains = Promise.await(Team.listByIds([...new Set(teamIds)], { projection: { _id: 1, name: 1 } }));
+
+ const results = result.map((room) => {
if (room.teamId) {
- const team = teams.find((team) => team._id === room.teamId);
+ const team = teamsMains.find((mainRoom) => mainRoom._id === room.teamId);
if (team) {
room.belongsTo = team.name;
}
@@ -202,7 +209,7 @@ const getUsers = (user, text, workspace, sort, pagination) => {
Meteor.methods({
browseChannels({ text = '', workspace = '', type = 'channels', sortBy = 'name', sortDirection = 'asc', page, offset, limit = 10 }) {
- const regex = new RegExp(s.trim(escapeRegExp(text)), 'i');
+ const searchTerm = s.trim(escapeRegExp(text));
if (!['channels', 'users', 'teams'].includes(type) || !['asc', 'desc'].includes(sortDirection) || ((!page && page !== 0) && (!offset && offset !== 0))) {
return;
@@ -230,9 +237,9 @@ Meteor.methods({
switch (type) {
case 'channels':
- return getChannels(user, canViewAnonymous, regex, sortChannels(sortBy, sortDirection), pagination);
+ return getChannelsAndGroups(user, canViewAnonymous, searchTerm, sortChannels(sortBy, sortDirection), pagination);
case 'teams':
- return getTeams(user, text, sortChannels(sortBy, sortDirection), pagination);
+ return getTeams(user, searchTerm, sortChannels(sortBy, sortDirection), pagination);
case 'users':
return getUsers(user, text, workspace, sortUsers(sortBy, sortDirection), pagination);
default:
diff --git a/server/sdk/types/ITeamService.ts b/server/sdk/types/ITeamService.ts
index c301b966c564..8709ae0c452c 100644
--- a/server/sdk/types/ITeamService.ts
+++ b/server/sdk/types/ITeamService.ts
@@ -82,4 +82,5 @@ export interface ITeamService {
getAllPublicTeams(options: FindOneOptions): Promise>;
getMembersByTeamIds(teamIds: Array, options: FindOneOptions): Promise>;
update(uid: string, teamId: string, updateData: ITeamUpdateData): Promise;
+ listTeamsBySubscriberUserId(uid: string, options?: FindOneOptions): Promise | null>;
}