diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6f7c44c3c04b..534f23be0100 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,9 +1,11 @@ /packages/* @RocketChat/chat-engine /packages/core-typings/ @RocketChat/chat-engine /packages/rest-typings/ @RocketChat/chat-engine +/packages/ui-contexts/ @RocketChat/frontend /packages/eslint-config/ @RocketChat/chat-engine /packages/livechat/ @RocketChat/frontend @RocketChat/chat-engine /.vscode/ @RocketChat/chat-engine /.github/ @RocketChat/chat-engine /_templates/ @RocketChat/chat-engine /apps/meteor/client/ @RocketChat/frontend +/apps/meteor/tests/ @RocketChat/chat-engine diff --git a/apps/meteor/app/api/server/api.d.ts b/apps/meteor/app/api/server/api.d.ts index 0bee475c759e..a868663634e8 100644 --- a/apps/meteor/app/api/server/api.d.ts +++ b/apps/meteor/app/api/server/api.d.ts @@ -8,6 +8,7 @@ import type { UrlParams, } from '@rocket.chat/rest-typings'; import type { IUser, IMethodConnection } from '@rocket.chat/core-typings'; +import type { ValidateFunction } from 'ajv'; import { ITwoFactorOptions } from '../../2fa/server/code'; @@ -54,7 +55,7 @@ export type NonEnterpriseTwoFactorOptions = { twoFactorOptions: ITwoFactorOptions; }; -type Options = +type Options = ( | { permissionsRequired?: string[]; authRequired?: boolean; @@ -64,7 +65,10 @@ type Options = authRequired: true; twoFactorRequired: true; twoFactorOptions?: ITwoFactorOptions; - }; + } +) & { + validateParams?: ValidateFunction; +}; type Request = { method: 'GET' | 'POST' | 'PUT' | 'DELETE'; @@ -80,9 +84,17 @@ type PartialThis = { type ActionThis = { urlParams: UrlParams; // TODO make it unsafe - readonly queryParams: TMethod extends 'GET' ? Partial> : Record; + readonly queryParams: TMethod extends 'GET' + ? TOptions extends { validateParams: ValidateFunction } + ? T + : Partial> + : Record; // TODO make it unsafe - readonly bodyParams: TMethod extends 'GET' ? Record : Partial>; + readonly bodyParams: TMethod extends 'GET' + ? Record + : TOptions extends { validateParams: ValidateFunction } + ? T + : Partial>; readonly request: Request; requestParams(): OperationParams; getLoggedInUser(): IUser | undefined; @@ -95,6 +107,7 @@ type ActionThis; query: Record; }; + /* @deprecated */ getUserFromParams(): IUser; } & (TOptions extends { authRequired: true } ? { diff --git a/apps/meteor/app/api/server/api.js b/apps/meteor/app/api/server/api.js index 9d6ddfb11718..7259e14cca5b 100644 --- a/apps/meteor/app/api/server/api.js +++ b/apps/meteor/app/api/server/api.js @@ -397,6 +397,9 @@ export class APIClass extends Restivus { try { api.enforceRateLimit(objectForRateLimitMatch, this.request, this.response, this.userId); + if (_options.validateParams && _options.validateParams(this.request.method === 'GET' ? this.queryParams : this.bodyParams)) { + throw new Meteor.Error('error-invalid-params', _options.validateParams.errors?.map((error) => error.message).join('\n ')); + } if (shouldVerifyPermissions && (!this.userId || !hasAllPermission(this.userId, _options.permissionsRequired))) { throw new Meteor.Error('error-unauthorized', 'User does not have the permissions required for this action', { permissions: _options.permissionsRequired, diff --git a/apps/meteor/app/api/server/index.ts b/apps/meteor/app/api/server/index.ts index ba35c423903c..3e2a60d115cb 100644 --- a/apps/meteor/app/api/server/index.ts +++ b/apps/meteor/app/api/server/index.ts @@ -12,7 +12,8 @@ import './helpers/requestParams'; import './helpers/isWidget'; import './default/info'; import './v1/assets'; -import './v1/channels'; +import './v1/channels.js'; +import './v1/channels.ts'; import './v1/chat'; import './v1/cloud'; import './v1/commands'; diff --git a/apps/meteor/app/api/server/v1/channels.js b/apps/meteor/app/api/server/v1/channels.js index 371a2de3d1c2..ce2590fcce3e 100644 --- a/apps/meteor/app/api/server/v1/channels.js +++ b/apps/meteor/app/api/server/v1/channels.js @@ -4,7 +4,7 @@ import _ from 'underscore'; import { Rooms, Subscriptions, Messages, Users } from '../../../models/server'; import { Integrations, Uploads } from '../../../models/server/raw'; -import { canAccessRoom, hasPermission, hasAtLeastOnePermission, hasAllPermission } from '../../../authorization/server'; +import { canAccessRoom, hasPermission, hasAtLeastOnePermission } from '../../../authorization/server'; import { mountIntegrationQueryBasedOnPermissions } from '../../../integrations/server/lib/mountQueriesBasedOnPermission'; import { normalizeMessagesForUser } from '../../../utils/server/lib/normalizeMessagesForUser'; import { API } from '../api'; @@ -42,24 +42,6 @@ function findChannelByIdOrName({ params, checkedArchived = true, userId }) { return room; } -API.v1.addRoute( - 'channels.addAll', - { authRequired: true }, - { - post() { - const findResult = findChannelByIdOrName({ params: this.requestParams() }); - - Meteor.runAsUser(this.userId, () => { - Meteor.call('addAllUserToRoom', findResult._id, this.bodyParams.activeUsersOnly); - }); - - return API.v1.success({ - channel: findChannelByIdOrName({ params: this.requestParams(), userId: this.userId }), - }); - }, - }, -); - API.v1.addRoute( 'channels.addModerator', { authRequired: true }, @@ -96,22 +78,6 @@ API.v1.addRoute( }, ); -API.v1.addRoute( - 'channels.archive', - { authRequired: true }, - { - post() { - const findResult = findChannelByIdOrName({ params: this.requestParams() }); - - Meteor.runAsUser(this.userId, () => { - Meteor.call('archiveRoom', findResult._id); - }); - - return API.v1.success(); - }, - }, -); - API.v1.addRoute( 'channels.close', { authRequired: true }, @@ -301,25 +267,6 @@ API.v1.addRoute( }, ); -API.v1.addRoute( - 'channels.delete', - { authRequired: true }, - { - post() { - const room = findChannelByIdOrName({ - params: this.requestParams(), - checkedArchived: false, - }); - - Meteor.runAsUser(this.userId, () => { - Meteor.call('eraseRoom', room._id); - }); - - return API.v1.success(); - }, - }, -); - API.v1.addRoute( 'channels.files', { authRequired: true }, @@ -424,62 +371,6 @@ API.v1.addRoute( }, ); -API.v1.addRoute( - 'channels.history', - { authRequired: true }, - { - get() { - const findResult = findChannelByIdOrName({ - params: this.requestParams(), - checkedArchived: false, - }); - - let latestDate = new Date(); - if (this.queryParams.latest) { - latestDate = new Date(this.queryParams.latest); - } - - let oldestDate = undefined; - if (this.queryParams.oldest) { - oldestDate = new Date(this.queryParams.oldest); - } - - const inclusive = this.queryParams.inclusive || false; - - let count = 20; - if (this.queryParams.count) { - count = parseInt(this.queryParams.count); - } - - let offset = 0; - if (this.queryParams.offset) { - offset = parseInt(this.queryParams.offset); - } - - const unreads = this.queryParams.unreads || false; - - const showThreadMessages = this.queryParams.showThreadMessages !== 'false'; - - const result = Meteor.call('getChannelHistory', { - rid: findResult._id, - latest: latestDate, - oldest: oldestDate, - inclusive, - offset, - count, - unreads, - showThreadMessages, - }); - - if (!result) { - return API.v1.unauthorized(); - } - - return API.v1.success(result); - }, - }, -); - API.v1.addRoute( 'channels.info', { authRequired: true }, @@ -509,65 +400,7 @@ API.v1.addRoute( return API.v1.failure('invalid-user-invite-list', 'Cannot invite if no users are provided'); } - Meteor.runAsUser(this.userId, () => { - Meteor.call('addUsersToRoom', { rid: findResult._id, users: users.map((u) => u.username) }); - }); - - return API.v1.success({ - channel: findChannelByIdOrName({ params: this.requestParams(), userId: this.userId }), - }); - }, - }, -); - -API.v1.addRoute( - 'channels.join', - { authRequired: true }, - { - post() { - const findResult = findChannelByIdOrName({ params: this.requestParams() }); - - Meteor.runAsUser(this.userId, () => { - Meteor.call('joinRoom', findResult._id, this.bodyParams.joinCode); - }); - - return API.v1.success({ - channel: findChannelByIdOrName({ params: this.requestParams(), userId: this.userId }), - }); - }, - }, -); - -API.v1.addRoute( - 'channels.kick', - { authRequired: true }, - { - post() { - const findResult = findChannelByIdOrName({ params: this.requestParams() }); - - const user = this.getUserFromParams(); - - Meteor.runAsUser(this.userId, () => { - Meteor.call('removeUserFromRoom', { rid: findResult._id, username: user.username }); - }); - - return API.v1.success({ - channel: findChannelByIdOrName({ params: this.requestParams(), userId: this.userId }), - }); - }, - }, -); - -API.v1.addRoute( - 'channels.leave', - { authRequired: true }, - { - post() { - const findResult = findChannelByIdOrName({ params: this.requestParams() }); - - Meteor.runAsUser(this.userId, () => { - Meteor.call('leaveRoom', findResult._id); - }); + Meteor.call('addUsersToRoom', { rid: findResult._id, users: users.map((u) => u.username) }); return API.v1.success({ channel: findChannelByIdOrName({ params: this.requestParams(), userId: this.userId }), @@ -721,50 +554,6 @@ API.v1.addRoute( }, ); -API.v1.addRoute( - 'channels.messages', - { authRequired: true }, - { - get() { - const findResult = findChannelByIdOrName({ - params: this.requestParams(), - checkedArchived: false, - }); - const { offset, count } = this.getPaginationItems(); - const { sort, fields, query } = this.parseJsonQuery(); - - const ourQuery = Object.assign({}, query, { rid: findResult._id }); - - // Special check for the permissions - if ( - hasPermission(this.userId, 'view-joined-room') && - !Subscriptions.findOneByRoomIdAndUserId(findResult._id, this.userId, { fields: { _id: 1 } }) - ) { - return API.v1.unauthorized(); - } - if (!hasPermission(this.userId, 'view-c-room')) { - return API.v1.unauthorized(); - } - - const cursor = Messages.find(ourQuery, { - sort: sort || { ts: -1 }, - skip: offset, - limit: count, - fields, - }); - - const total = cursor.count(); - const messages = cursor.fetch(); - - return API.v1.success({ - messages: normalizeMessagesForUser(messages, this.userId), - count: messages.length, - offset, - total, - }); - }, - }, -); // TODO: CACHE: I dont like this method( functionality and how we implemented ) its very expensive // TODO check if this code is better or not // RocketChat.API.v1.addRoute('channels.online', { authRequired: true }, { @@ -841,35 +630,6 @@ API.v1.addRoute( }, ); -API.v1.addRoute( - 'channels.open', - { authRequired: true }, - { - post() { - const findResult = findChannelByIdOrName({ - params: this.requestParams(), - checkedArchived: false, - }); - - const sub = Subscriptions.findOneByRoomIdAndUserId(findResult._id, this.userId); - - if (!sub) { - return API.v1.failure(`The user/callee is not in the channel "${findResult.name}".`); - } - - if (sub.open) { - return API.v1.failure(`The channel, ${findResult.name}, is already open to the sender`); - } - - Meteor.runAsUser(this.userId, () => { - Meteor.call('openRoom', findResult._id); - }); - - return API.v1.success(); - }, - }, -); - API.v1.addRoute( 'channels.removeModerator', { authRequired: true }, @@ -1065,32 +825,6 @@ API.v1.addRoute( }, ); -API.v1.addRoute( - 'channels.setReadOnly', - { authRequired: true }, - { - post() { - if (typeof this.bodyParams.readOnly === 'undefined') { - return API.v1.failure('The bodyParam "readOnly" is required'); - } - - const findResult = findChannelByIdOrName({ params: this.requestParams() }); - - if (findResult.ro === this.bodyParams.readOnly) { - return API.v1.failure('The channel read only setting is the same as what it would be changed to.'); - } - - Meteor.runAsUser(this.userId, () => { - Meteor.call('saveRoomSettings', findResult._id, 'readOnly', this.bodyParams.readOnly); - }); - - return API.v1.success({ - channel: findChannelByIdOrName({ params: this.requestParams(), userId: this.userId }), - }); - }, - }, -); - API.v1.addRoute( 'channels.setTopic', { authRequired: true }, @@ -1117,28 +851,6 @@ API.v1.addRoute( }, ); -API.v1.addRoute( - 'channels.setAnnouncement', - { authRequired: true }, - { - post() { - if (!this.bodyParams.hasOwnProperty('announcement')) { - return API.v1.failure('The bodyParam "announcement" is required'); - } - - const findResult = findChannelByIdOrName({ params: this.requestParams() }); - - Meteor.runAsUser(this.userId, () => { - Meteor.call('saveRoomSettings', findResult._id, 'roomAnnouncement', this.bodyParams.announcement); - }); - - return API.v1.success({ - announcement: this.bodyParams.announcement, - }); - }, - }, -); - API.v1.addRoute( 'channels.setType', { authRequired: true }, @@ -1165,106 +877,6 @@ API.v1.addRoute( }, ); -API.v1.addRoute( - 'channels.unarchive', - { authRequired: true }, - { - post() { - const findResult = findChannelByIdOrName({ - params: this.requestParams(), - checkedArchived: false, - }); - - if (!findResult.archived) { - return API.v1.failure(`The channel, ${findResult.name}, is not archived`); - } - - Meteor.runAsUser(this.userId, () => { - Meteor.call('unarchiveRoom', findResult._id); - }); - - return API.v1.success(); - }, - }, -); - -API.v1.addRoute( - 'channels.getAllUserMentionsByChannel', - { authRequired: true }, - { - get() { - const { roomId } = this.requestParams(); - const { offset, count } = this.getPaginationItems(); - const { sort } = this.parseJsonQuery(); - - if (!roomId) { - return API.v1.failure('The request param "roomId" is required'); - } - - const mentions = Meteor.runAsUser(this.userId, () => - Meteor.call('getUserMentionsByChannel', { - roomId, - options: { - sort: sort || { ts: 1 }, - skip: offset, - limit: count, - }, - }), - ); - - const allMentions = Meteor.runAsUser(this.userId, () => - Meteor.call('getUserMentionsByChannel', { - roomId, - options: {}, - }), - ); - - return API.v1.success({ - mentions, - count: mentions.length, - offset, - total: allMentions.length, - }); - }, - }, -); - -API.v1.addRoute( - 'channels.roles', - { authRequired: true }, - { - get() { - const findResult = findChannelByIdOrName({ params: this.requestParams() }); - - const roles = Meteor.runAsUser(this.userId, () => Meteor.call('getRoomRoles', findResult._id)); - - return API.v1.success({ - roles, - }); - }, - }, -); - -API.v1.addRoute( - 'channels.moderators', - { authRequired: true }, - { - get() { - const findResult = findChannelByIdOrName({ params: this.requestParams() }); - - const moderators = Subscriptions.findByRoomIdAndRoles(findResult._id, ['moderator'], { - fields: { u: 1 }, - }) - .fetch() - .map((sub) => sub.u); - - return API.v1.success({ - moderators, - }); - }, - }, -); - API.v1.addRoute( 'channels.addLeader', { authRequired: true }, @@ -1340,55 +952,3 @@ API.v1.addRoute( }, }, ); - -API.v1.addRoute( - 'channels.convertToTeam', - { authRequired: true }, - { - post() { - if (!hasAllPermission(this.userId, ['create-team', 'edit-room'])) { - return API.v1.unauthorized(); - } - - const { channelId, channelName } = this.bodyParams; - - if (!channelId && !channelName) { - return API.v1.failure('The parameter "channelId" or "channelName" is required'); - } - - const room = findChannelByIdOrName({ - params: { - roomId: channelId, - roomName: channelName, - }, - userId: this.userId, - }); - - if (!room) { - return API.v1.failure('Channel not found'); - } - - const subscriptions = Subscriptions.findByRoomId(room._id, { - fields: { 'u._id': 1 }, - }); - - const members = subscriptions.fetch().map((s) => s.u && s.u._id); - - const teamData = { - team: { - name: room.name, - type: room.t === 'c' ? 0 : 1, - }, - members, - room: { - name: room.name, - id: room._id, - }, - }; - - const team = Promise.await(Team.create(this.userId, teamData)); - - return API.v1.success({ team }); - }, - }, -); diff --git a/apps/meteor/app/api/server/v1/channels.ts b/apps/meteor/app/api/server/v1/channels.ts new file mode 100644 index 000000000000..8d4c21ef3512 --- /dev/null +++ b/apps/meteor/app/api/server/v1/channels.ts @@ -0,0 +1,522 @@ +import { Meteor } from 'meteor/meteor'; +import type { IRoom, ISubscription } from '@rocket.chat/core-typings'; +import { + isChannelsAddAllProps, + isChannelsArchiveProps, + isChannelsHistoryProps, + isChannelsUnarchiveProps, + isChannelsRolesProps, + isChannelsJoinProps, + isChannelsKickProps, + isChannelsLeaveProps, + isChannelsMessagesProps, + isChannelsOpenProps, + isChannelsSetAnnouncementProps, + isChannelsGetAllUserMentionsByChannelProps, + isChannelsModeratorsProps, + isChannelsConvertToTeamProps, + isChannelsSetReadOnlyProps, + isChannelsDeleteProps, +} from '@rocket.chat/rest-typings'; + +import { Rooms, Subscriptions, Messages } from '../../../models/server'; +import { hasPermission, hasAllPermission } from '../../../authorization/server'; +import { normalizeMessagesForUser } from '../../../utils/server/lib/normalizeMessagesForUser'; +import { API } from '../api'; +import { Team } from '../../../../server/sdk'; + +// Returns the channel IF found otherwise it will return the failure of why it didn't. Check the `statusCode` property +function findChannelByIdOrName({ + params, + checkedArchived = true, + userId, +}: { + params: + | { + roomId: string; + } + | { + roomName: string; + }; + userId?: string; + checkedArchived?: boolean; +}): IRoom { + const fields = { ...API.v1.defaultFieldsToExclude }; + + const room: IRoom = 'roomId' in params ? Rooms.findOneById(params.roomId, { fields }) : Rooms.findOneByName(params.roomName, { fields }); + + if (!room || (room.t !== 'c' && room.t !== 'l')) { + throw new Meteor.Error('error-room-not-found', 'The required "roomId" or "roomName" param provided does not match any channel'); + } + + if (checkedArchived && room.archived) { + throw new Meteor.Error('error-room-archived', `The channel, ${room.name}, is archived`); + } + if (userId && room.lastMessage) { + const [lastMessage] = normalizeMessagesForUser([room.lastMessage], userId); + room.lastMessage = lastMessage; + } + + return room; +} + +API.v1.addRoute( + 'channels.addAll', + { authRequired: true }, + { + post() { + if (!isChannelsAddAllProps(this.bodyParams)) { + throw new Meteor.Error('error-invalid-params', isChannelsAddAllProps.errors?.map((error: any) => error.message).join('\n ')); + } + + const { activeUsersOnly, ...params } = this.bodyParams; + const findResult = findChannelByIdOrName({ params, userId: this.userId }); + + Meteor.call('addAllUserToRoom', findResult._id, activeUsersOnly); + + return API.v1.success({ + channel: findChannelByIdOrName({ params, userId: this.userId }), + }); + }, + }, +); + +API.v1.addRoute( + 'channels.archive', + { authRequired: true }, + { + post() { + if (!isChannelsArchiveProps(this.bodyParams)) { + throw new Meteor.Error('error-invalid-params', isChannelsArchiveProps.errors?.map((error: any) => error.message).join('\n ')); + } + + const findResult = findChannelByIdOrName({ params: this.bodyParams }); + + Meteor.call('archiveRoom', findResult._id); + + return API.v1.success(); + }, + }, +); + +API.v1.addRoute( + 'channels.unarchive', + { authRequired: true }, + { + post() { + if (!isChannelsUnarchiveProps(this.bodyParams)) { + throw new Meteor.Error('error-invalid-params', isChannelsUnarchiveProps.errors?.map((error: any) => error.message).join('\n ')); + } + + const findResult = findChannelByIdOrName({ + params: this.bodyParams, + checkedArchived: false, + }); + + if (!findResult.archived) { + return API.v1.failure(`The channel, ${findResult.name}, is not archived`); + } + + Meteor.call('unarchiveRoom', findResult._id); + + return API.v1.success(); + }, + }, +); + +API.v1.addRoute( + 'channels.history', + { authRequired: true }, + { + get() { + if (!isChannelsHistoryProps(this.queryParams)) { + throw new Meteor.Error('error-invalid-params', isChannelsHistoryProps.errors?.map((error: any) => error.message).join('\n ')); + } + const { roomId, unreads, oldest, latest, showThreadMessages, inclusive } = this.queryParams; + const findResult = findChannelByIdOrName({ + params: { roomId }, + checkedArchived: false, + }); + + const { count = 20, offset = 0 } = this.getPaginationItems(); + + const result = Meteor.call('getChannelHistory', { + rid: findResult._id, + latest: latest ? new Date(latest) : new Date(), + oldest: oldest && new Date(oldest), + inclusive: inclusive === 'true', + offset, + count, + unreads: unreads === 'true', + showThreadMessages: showThreadMessages === 'true', + }); + + if (!result) { + return API.v1.unauthorized(); + } + + return API.v1.success(result); + }, + }, +); + +API.v1.addRoute( + 'channels.roles', + { authRequired: true }, + { + get() { + if (!isChannelsRolesProps(this.queryParams)) { + throw new Meteor.Error('error-invalid-params', isChannelsRolesProps.errors?.map((error: any) => error.message).join('\n ')); + } + const findResult = findChannelByIdOrName({ params: this.queryParams }); + + const roles = Meteor.call('getRoomRoles', findResult._id); + + return API.v1.success({ + roles, + }); + }, + }, +); + +API.v1.addRoute( + 'channels.join', + { authRequired: true }, + { + post() { + if (!isChannelsJoinProps(this.bodyParams)) { + throw new Meteor.Error('error-invalid-params', isChannelsJoinProps.errors?.map((error: any) => error.message).join('\n ')); + } + + const { roomId, joinCode } = this.bodyParams; + const findResult = findChannelByIdOrName({ params: { roomId } }); + + Meteor.call('joinRoom', findResult._id, joinCode); + + return API.v1.success({ + channel: findChannelByIdOrName({ params: { roomId }, userId: this.userId }), + }); + }, + }, +); + +API.v1.addRoute( + 'channels.kick', + { authRequired: true }, + { + post() { + if (!isChannelsKickProps(this.bodyParams)) { + throw new Meteor.Error('error-invalid-params', isChannelsKickProps.errors?.map((error: any) => error.message).join('\n ')); + } + const { roomId /* userId */ } = this.bodyParams; + const findResult = findChannelByIdOrName({ params: { roomId } }); + + const user = this.getUserFromParams(); + + Meteor.call('removeUserFromRoom', { rid: findResult._id, username: user.username }); + + return API.v1.success({ + channel: findChannelByIdOrName({ params: { roomId }, userId: this.userId }), + }); + }, + }, +); + +API.v1.addRoute( + 'channels.leave', + { authRequired: true }, + { + post() { + if (!isChannelsLeaveProps(this.bodyParams)) { + throw new Meteor.Error('error-invalid-params', isChannelsLeaveProps.errors?.map((error: any) => error.message).join('\n ')); + } + + const { roomId } = this.bodyParams; + const findResult = findChannelByIdOrName({ params: { roomId } }); + + Meteor.runAsUser(this.userId, () => { + Meteor.call('leaveRoom', findResult._id); + }); + + return API.v1.success({ + channel: findChannelByIdOrName({ params: { roomId }, userId: this.userId }), + }); + }, + }, +); + +API.v1.addRoute( + 'channels.messages', + { authRequired: true }, + { + get() { + if (!isChannelsMessagesProps(this.queryParams)) { + throw new Meteor.Error('error-invalid-params', isChannelsMessagesProps.errors?.map((error: any) => error.message).join('\n ')); + } + const { roomId } = this.queryParams; + const findResult = findChannelByIdOrName({ + params: { roomId }, + checkedArchived: false, + }); + const { offset, count } = this.getPaginationItems(); + const { sort, fields, query } = this.parseJsonQuery(); + + const ourQuery = { ...query, rid: findResult._id }; + + // Special check for the permissions + if ( + hasPermission(this.userId, 'view-joined-room') && + !Subscriptions.findOneByRoomIdAndUserId(findResult._id, this.userId, { fields: { _id: 1 } }) + ) { + return API.v1.unauthorized(); + } + if (!hasPermission(this.userId, 'view-c-room')) { + return API.v1.unauthorized(); + } + + const cursor = Messages.find(ourQuery, { + sort: sort || { ts: -1 }, + skip: offset, + limit: count, + fields, + }); + + const total = cursor.count(); + const messages = cursor.fetch(); + + return API.v1.success({ + messages: normalizeMessagesForUser(messages, this.userId), + count: messages.length, + offset, + total, + }); + }, + }, +); + +API.v1.addRoute( + 'channels.open', + { authRequired: true }, + { + post() { + if (!isChannelsOpenProps(this.bodyParams)) { + throw new Meteor.Error('error-invalid-params', isChannelsOpenProps.errors?.map((error: any) => error.message).join('\n ')); + } + + const { roomId } = this.bodyParams; + + const findResult = findChannelByIdOrName({ + params: { roomId }, + checkedArchived: false, + }); + + const sub = Subscriptions.findOneByRoomIdAndUserId(findResult._id, this.userId); + + if (!sub) { + return API.v1.failure(`The user/callee is not in the channel "${findResult.name}".`); + } + + if (sub.open) { + return API.v1.failure(`The channel, ${findResult.name}, is already open to the sender`); + } + + Meteor.call('openRoom', findResult._id); + + return API.v1.success(); + }, + }, +); + +API.v1.addRoute( + 'channels.setReadOnly', + { authRequired: true }, + { + post() { + if (!isChannelsSetReadOnlyProps(this.bodyParams)) { + throw new Meteor.Error('error-invalid-params', isChannelsSetReadOnlyProps.errors?.map((error: any) => error.message).join('\n ')); + } + + const { roomId } = this.bodyParams; + + const findResult = findChannelByIdOrName({ params: { roomId } }); + + if (findResult.ro === this.bodyParams.readOnly) { + return API.v1.failure('The channel read only setting is the same as what it would be changed to.'); + } + + Meteor.call('saveRoomSettings', findResult._id, 'readOnly', this.bodyParams.readOnly); + + return API.v1.success({ + channel: findChannelByIdOrName({ params: { roomId }, userId: this.userId }), + }); + }, + }, +); + +API.v1.addRoute( + 'channels.setAnnouncement', + { authRequired: true }, + { + post() { + if (!isChannelsSetAnnouncementProps(this.bodyParams)) { + throw new Meteor.Error( + 'error-invalid-params', + isChannelsSetAnnouncementProps.errors?.map((error: any) => error.message).join('\n '), + ); + } + const { roomId, announcement } = this.bodyParams; + + const findResult = findChannelByIdOrName({ params: { roomId } }); + + Meteor.call('saveRoomSettings', findResult._id, 'roomAnnouncement', announcement); + + return API.v1.success({ + announcement: this.bodyParams.announcement, + }); + }, + }, +); + +API.v1.addRoute( + 'channels.getAllUserMentionsByChannel', + { authRequired: true }, + { + get() { + if (!isChannelsGetAllUserMentionsByChannelProps(this.queryParams)) { + throw new Meteor.Error( + 'error-invalid-params', + isChannelsGetAllUserMentionsByChannelProps.errors?.map((error: any) => error.message).join('\n '), + ); + } + const { roomId } = this.queryParams; + const { offset, count } = this.getPaginationItems(); + const { sort } = this.parseJsonQuery(); + + const mentions = Meteor.runAsUser(this.userId, () => + Meteor.call('getUserMentionsByChannel', { + roomId, + options: { + sort: sort || { ts: 1 }, + skip: offset, + limit: count, + }, + }), + ); + + const allMentions = Meteor.runAsUser(this.userId, () => + Meteor.call('getUserMentionsByChannel', { + roomId, + options: {}, + }), + ); + + return API.v1.success({ + mentions, + count: mentions.length, + offset, + total: allMentions.length, + }); + }, + }, +); + +API.v1.addRoute( + 'channels.moderators', + { authRequired: true }, + { + get() { + if (!isChannelsModeratorsProps(this.queryParams)) { + throw new Meteor.Error('error-invalid-params', isChannelsModeratorsProps.errors?.map((error: any) => error.message).join('\n ')); + } + const { roomId } = this.queryParams; + + const findResult = findChannelByIdOrName({ params: { roomId } }); + + const moderators = Subscriptions.findByRoomIdAndRoles(findResult._id, ['moderator'], { + fields: { u: 1 }, + }) + .fetch() + .map((sub: ISubscription) => sub.u); + + return API.v1.success({ + moderators, + }); + }, + }, +); + +API.v1.addRoute( + 'channels.delete', + { authRequired: true }, + { + post() { + if (!isChannelsDeleteProps(this.bodyParams)) { + throw new Meteor.Error('error-invalid-params', isChannelsDeleteProps.errors?.map((error: any) => error.message).join('\n ')); + } + const room = findChannelByIdOrName({ + params: this.bodyParams, + checkedArchived: false, + }); + + Meteor.call('eraseRoom', room._id); + + return API.v1.success(); + }, + }, +); + +API.v1.addRoute( + 'channels.convertToTeam', + { authRequired: true }, + { + async post() { + if (!isChannelsConvertToTeamProps(this.bodyParams)) { + throw new Meteor.Error('error-invalid-params', isChannelsConvertToTeamProps.errors?.map((error: any) => error.message).join('\n ')); + } + + if (!hasAllPermission(this.userId, ['create-team', 'edit-room'])) { + return API.v1.unauthorized(); + } + + const { channelId, channelName } = this.bodyParams; + + if (!channelId && !channelName) { + return API.v1.failure('The parameter "channelId" or "channelName" is required'); + } + + const room = findChannelByIdOrName({ + params: { + roomId: channelId, + roomName: channelName, + }, + userId: this.userId, + }); + + if (!room) { + return API.v1.failure('Channel not found'); + } + + const subscriptions = Subscriptions.findByRoomId(room._id, { + fields: { 'u._id': 1 }, + }); + + const members = subscriptions.fetch().map((s: ISubscription) => s.u && s.u._id); + + const teamData = { + team: { + name: room.name ?? '', + type: room.t === 'c' ? 0 : 1, + }, + members, + room: { + name: room.name, + id: room._id, + }, + }; + + const team = await Team.create(this.userId, teamData); + + return API.v1.success({ team }); + }, + }, +); diff --git a/apps/meteor/app/authorization/client/startup.js b/apps/meteor/app/authorization/client/startup.js index 8bdc2c958e27..7b1643224acd 100644 --- a/apps/meteor/app/authorization/client/startup.js +++ b/apps/meteor/app/authorization/client/startup.js @@ -1,12 +1,10 @@ import { Meteor } from 'meteor/meteor'; import { Tracker } from 'meteor/tracker'; -import { hasAtLeastOnePermission } from './hasPermission'; import { CachedCollectionManager } from '../../ui-cached-collection'; import { APIClient } from '../../utils/client'; import { Roles } from '../../models/client'; import { rolesStreamer } from './lib/streamer'; -import { registerAdminSidebarItem } from '../../../client/views/admin'; Meteor.startup(() => { CachedCollectionManager.onLogin(async () => { @@ -18,14 +16,6 @@ Meteor.startup(() => { Roles.ready.set(true); }); - registerAdminSidebarItem({ - href: 'admin-permissions', - i18nLabel: 'Permissions', - icon: 'lock', - permissionGranted() { - return hasAtLeastOnePermission(['access-permissions', 'access-setting-permissions']); - }, - }); const events = { changed: (role) => { delete role.type; diff --git a/apps/meteor/app/autotranslate/client/lib/tabBar.ts b/apps/meteor/app/autotranslate/client/lib/tabBar.ts index 2690cdfe67a3..fe564c7bd6b0 100644 --- a/apps/meteor/app/autotranslate/client/lib/tabBar.ts +++ b/apps/meteor/app/autotranslate/client/lib/tabBar.ts @@ -1,8 +1,7 @@ import { lazy, useMemo } from 'react'; +import { useSetting, usePermission } from '@rocket.chat/ui-contexts'; import { addAction } from '../../../../client/views/room/lib/Toolbox'; -import { usePermission } from '../../../../client/contexts/AuthorizationContext'; -import { useSetting } from '../../../../client/contexts/SettingsContext'; addAction('autotranslate', () => { const hasPermission = usePermission('auto-translate'); diff --git a/apps/meteor/app/discussion/client/tabBar.ts b/apps/meteor/app/discussion/client/tabBar.ts index 2c225cca4862..fc5f0934cfd5 100644 --- a/apps/meteor/app/discussion/client/tabBar.ts +++ b/apps/meteor/app/discussion/client/tabBar.ts @@ -1,7 +1,7 @@ import { useMemo, lazy } from 'react'; +import { useSetting } from '@rocket.chat/ui-contexts'; import { addAction } from '../../../client/views/room/lib/Toolbox'; -import { useSetting } from '../../../client/contexts/SettingsContext'; const template = lazy(() => import('../../../client/views/room/contextualBar/Discussions')); diff --git a/apps/meteor/app/e2e/client/tabbar.ts b/apps/meteor/app/e2e/client/tabbar.ts index 6793405b98e8..0d9b5e435c55 100644 --- a/apps/meteor/app/e2e/client/tabbar.ts +++ b/apps/meteor/app/e2e/client/tabbar.ts @@ -1,10 +1,8 @@ import { useMemo, useCallback } from 'react'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useSetting, usePermission, useMethod } from '@rocket.chat/ui-contexts'; import { addAction } from '../../../client/views/room/lib/Toolbox'; -import { useSetting } from '../../../client/contexts/SettingsContext'; -import { usePermission } from '../../../client/contexts/AuthorizationContext'; -import { useMethod } from '../../../client/contexts/ServerContext'; import { useReactiveValue } from '../../../client/hooks/useReactiveValue'; import { e2e } from './rocketchat.e2e'; diff --git a/apps/meteor/app/emoji-custom/client/admin/startup.js b/apps/meteor/app/emoji-custom/client/admin/startup.js deleted file mode 100644 index 4c3054862df6..000000000000 --- a/apps/meteor/app/emoji-custom/client/admin/startup.js +++ /dev/null @@ -1,11 +0,0 @@ -import { registerAdminSidebarItem } from '../../../../client/views/admin'; -import { hasPermission } from '../../../authorization'; - -registerAdminSidebarItem({ - href: 'emoji-custom', - i18nLabel: 'Custom_Emoji', - icon: 'emoji', - permissionGranted() { - return hasPermission('manage-emoji'); - }, -}); diff --git a/apps/meteor/app/emoji-custom/client/index.js b/apps/meteor/app/emoji-custom/client/index.js index 8432b7675b3b..d8a1b75e275d 100644 --- a/apps/meteor/app/emoji-custom/client/index.js +++ b/apps/meteor/app/emoji-custom/client/index.js @@ -1,4 +1,3 @@ import './lib/emojiCustom'; import './notifications/deleteEmojiCustom'; import './notifications/updateEmojiCustom'; -import './admin/startup'; diff --git a/apps/meteor/app/federation-v2/server/bridge.ts b/apps/meteor/app/federation-v2/server/bridge.ts index d02c2b674adc..21457fc56101 100644 --- a/apps/meteor/app/federation-v2/server/bridge.ts +++ b/apps/meteor/app/federation-v2/server/bridge.ts @@ -1,4 +1,4 @@ -import { Bridge, AppServiceRegistration } from '@rocket.chat/forked-matrix-appservice-bridge'; +import { Bridge as MatrixBridge, AppServiceRegistration } from '@rocket.chat/forked-matrix-appservice-bridge'; import { settings } from '../../settings/server'; import { IMatrixEvent } from './definitions/IMatrixEvent'; @@ -6,23 +6,64 @@ import { MatrixEventType } from './definitions/MatrixEventType'; import { addToQueue } from './queue'; import { getRegistrationInfo } from './config'; -export const matrixBridge = new Bridge({ - homeserverUrl: settings.get('Federation_Matrix_homeserver_url'), - domain: settings.get('Federation_Matrix_homeserver_domain'), - registration: AppServiceRegistration.fromObject(getRegistrationInfo()), - disableStores: true, - controller: { - onAliasQuery: (alias, matrixRoomId): void => { - console.log('onAliasQuery', alias, matrixRoomId); - }, - onEvent: async (request /* , context*/): Promise => { - // Get the event - const event = request.getData() as unknown as IMatrixEvent; - - addToQueue(event); - }, - onLog: async (line, isError): Promise => { - console.log(line, isError); - }, - }, -}); +class Bridge { + private bridgeInstance: MatrixBridge; + + private isRunning = false; + + public async start(): Promise { + try { + await this.stop(); + } finally { + this.createInstance(); + if (!this.isRunning) { + await this.bridgeInstance.run(this.getBridgePort()); + this.isRunning = true; + } + } + } + + public async stop(): Promise { + if (!this.isRunning) { + return; + } + // the http server can take some minutes to shutdown and this promise to be resolved + await this.bridgeInstance.close(); + this.isRunning = false; + } + + public getInstance(): MatrixBridge { + return this.bridgeInstance; + } + + private createInstance(): void { + this.bridgeInstance = new MatrixBridge({ + homeserverUrl: settings.get('Federation_Matrix_homeserver_url'), + domain: settings.get('Federation_Matrix_homeserver_domain'), + registration: AppServiceRegistration.fromObject(getRegistrationInfo()), + disableStores: true, + controller: { + onAliasQuery: (alias, matrixRoomId): void => { + console.log('onAliasQuery', alias, matrixRoomId); + }, + onEvent: async (request /* , context*/): Promise => { + // Get the event + const event = request.getData() as unknown as IMatrixEvent; + + addToQueue(event); + }, + onLog: async (line, isError): Promise => { + console.log(line, isError); + }, + }, + }); + } + + private getBridgePort(): number { + const [, , port] = settings.get('Federation_Matrix_bridge_url').split(':'); + + return parseInt(port); + } +} + +export const matrixBridge = new Bridge(); diff --git a/apps/meteor/app/federation-v2/server/index.ts b/apps/meteor/app/federation-v2/server/index.ts index 8577336ac9c6..e331badfd006 100644 --- a/apps/meteor/app/federation-v2/server/index.ts +++ b/apps/meteor/app/federation-v2/server/index.ts @@ -1,2 +1,4 @@ import './settings'; -import './startup'; +import { startBridge } from './startup'; + +startBridge(); diff --git a/apps/meteor/app/federation-v2/server/matrix-client/message.ts b/apps/meteor/app/federation-v2/server/matrix-client/message.ts index ef48ba607ecd..a6a9d8626632 100644 --- a/apps/meteor/app/federation-v2/server/matrix-client/message.ts +++ b/apps/meteor/app/federation-v2/server/matrix-client/message.ts @@ -18,7 +18,7 @@ export const send = async (message: IMessage): Promise => { throw new Error(`Could not find room matrix id for ${message.rid}`); } - const intent = matrixBridge.getIntent(userMatrixId); + const intent = matrixBridge.getInstance().getIntent(userMatrixId); await intent.sendText(roomMatrixId, message.msg || '...not-supported...'); return message; diff --git a/apps/meteor/app/federation-v2/server/matrix-client/room.ts b/apps/meteor/app/federation-v2/server/matrix-client/room.ts index 820e1e77b6cd..21c7a2b00f84 100644 --- a/apps/meteor/app/federation-v2/server/matrix-client/room.ts +++ b/apps/meteor/app/federation-v2/server/matrix-client/room.ts @@ -23,7 +23,7 @@ export const create = async (user: IUser, room: IRoom): Promise matrixUserId.replace('@', ''); +const formatUserIdAsRCUsername = (userId = ''): string => removeUselessCharsFromMatrixId(userId.split(':')[0]); + export const invite = async (inviterId: string, roomId: string, invitedId: string): Promise => { console.log(`[${inviterId}-${invitedId}-${roomId}] Inviting user ${invitedId} to ${roomId}...`); @@ -55,11 +58,13 @@ export const invite = async (inviterId: string, roomId: string, invitedId: strin const invitedUserIsRemote = invitedUserDomain && invitedUserDomain !== settings.get('Federation_Matrix_homeserver_domain'); // Find the invited user in Rocket.Chats users - let invitedUser = Users.findOneByUsername(invitedId.replace('@', '')); + // TODO: this should be refactored asap, since these variable value changes lead us to confusion + let invitedUser = Users.findOneByUsername(removeUselessCharsFromMatrixId(invitedId)); if (!invitedUser) { // Create the invited user - invitedUser = await matrixClient.user.createLocal(invitedUserMatrixId); + const { uid } = await matrixClient.user.createLocal(invitedUserMatrixId); + invitedUser = Users.findOneById(uid); } // If the invited user is not remote, let's ensure it exists remotely @@ -85,14 +90,14 @@ export const invite = async (inviterId: string, roomId: string, invitedId: strin // Invite && Auto-join if the user is Rocket.Chat controlled if (!invitedUserIsRemote) { // Invite the user to the room - await matrixBridge.getIntent(inviterUser.mui).invite(matrixRoomId, invitedUserMatrixId); + await matrixBridge.getInstance().getIntent(inviterUser.mui).invite(matrixRoomId, invitedUserMatrixId); console.log(`[${inviterId}-${invitedId}-${roomId}] Auto-join room...`); - await matrixBridge.getIntent(invitedUserMatrixId).join(matrixRoomId); + await matrixBridge.getInstance().getIntent(invitedUserMatrixId).join(matrixRoomId); } else { // Invite the user to the room but don't wait as this is dependent on the user accepting the invite because we don't control this user - matrixBridge.getIntent(inviterUser.mui).invite(matrixRoomId, invitedUserMatrixId); + matrixBridge.getInstance().getIntent(inviterUser.mui).invite(matrixRoomId, invitedUserMatrixId); } // Add the matrix user to the invited room @@ -104,7 +109,7 @@ export const createRemote = async (u: IUser): Promise => { console.log(`Creating remote user ${matrixUserId}...`); - const intent = matrixBridge.getIntent(matrixUserId); + const intent = matrixBridge.getInstance().getIntent(matrixUserId); await intent.ensureProfile(u.name); @@ -117,10 +122,28 @@ export const createRemote = async (u: IUser): Promise => { return payload; }; +const createLocalUserIfNotExists = async (userId = '', profileInfo: MatrixProfileInfo = {}): Promise => { + const existingUser = await Users.findOneByUsername(formatUserIdAsRCUsername(userId)); + + if (existingUser) { + return existingUser._id; + } + + return Users.create({ + username: removeUselessCharsFromMatrixId(userId), + type: 'user', + status: 'online', + active: true, + roles: ['user'], + name: profileInfo.displayname, + requirePasswordChange: false, + }); +}; + export const createLocal = async (matrixUserId: string): Promise => { console.log(`Creating local user ${matrixUserId}...`); - const intent = matrixBridge.getIntent(matrixUserId); + const intent = matrixBridge.getInstance().getIntent(matrixUserId); let currentProfile: MatrixProfileInfo = {}; @@ -130,16 +153,7 @@ export const createLocal = async (matrixUserId: string): Promise { - if (!isFederationMatrixEnabled()) return; +const watchChanges = (): void => { + settings.watchMultiple( + [ + 'Federation_Matrix_enabled', + 'Federation_Matrix_id', + 'Federation_Matrix_hs_token', + 'Federation_Matrix_as_token', + 'Federation_Matrix_homeserver_url', + 'Federation_Matrix_homeserver_domain', + 'Federation_Matrix_bridge_url', + 'Federation_Matrix_bridge_localpart', + ], + async ([enabled]) => { + setupLogger.info(`Federation Matrix is ${enabled ? 'enabled' : 'disabled'}`); + if (!enabled) { + await matrixBridge.stop(); + return; + } + await matrixBridge.start(); + }, + ); +}; + +export const startBridge = (): void => { + watchChanges(); bridgeLogger.info(`Running Federation V2: - id: ${settings.get('Federation_Matrix_id')} + id: ${settings.get('Federation_Matrix_id')} bridgeUrl: ${settings.get('Federation_Matrix_bridge_url')} - homeserverURL: ${settings.get('Federation_Matrix_homeserver_url')} - homeserverDomain: ${settings.get('Federation_Matrix_homeserver_domain')} + homeserverURL: ${settings.get('Federation_Matrix_homeserver_url')} + homeserverDomain: ${settings.get('Federation_Matrix_homeserver_domain')} `); - - const [, , port] = settings.get('Federation_Matrix_bridge_url').split(':') as bridgeUrlTuple; - - matrixBridge.run(port); - - // TODO: Changes here should re-initialize the bridge instead of needing a restart - // Add settings listeners - settings.watch('Federation_Matrix_enabled', (value) => { - setupLogger.info(`Federation Matrix is ${value ? 'enabled' : 'disabled'}`); - }); -})(); +}; diff --git a/apps/meteor/app/federation-v2/server/tools.ts b/apps/meteor/app/federation-v2/server/tools.ts deleted file mode 100644 index 8e475df2fe73..000000000000 --- a/apps/meteor/app/federation-v2/server/tools.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { settings } from '../../settings/server'; -import { matrixBridge } from './bridge'; - -export const isFederationMatrixEnabled = (): boolean => !!(settings.get('Federation_Matrix_enabled') && matrixBridge); diff --git a/apps/meteor/app/integrations/client/startup.js b/apps/meteor/app/integrations/client/startup.js deleted file mode 100644 index 58b94ea49df6..000000000000 --- a/apps/meteor/app/integrations/client/startup.js +++ /dev/null @@ -1,15 +0,0 @@ -import { hasAtLeastOnePermission } from '../../authorization'; -import { registerAdminSidebarItem } from '../../../client/views/admin'; - -registerAdminSidebarItem({ - href: 'admin-integrations', - i18nLabel: 'Integrations', - icon: 'code', - permissionGranted: () => - hasAtLeastOnePermission([ - 'manage-outgoing-integrations', - 'manage-own-outgoing-integrations', - 'manage-incoming-integrations', - 'manage-own-incoming-integrations', - ]), -}); diff --git a/apps/meteor/app/livechat/client/externalFrame/tabBar.ts b/apps/meteor/app/livechat/client/externalFrame/tabBar.ts index f79b36c521bd..2d5baf5caead 100644 --- a/apps/meteor/app/livechat/client/externalFrame/tabBar.ts +++ b/apps/meteor/app/livechat/client/externalFrame/tabBar.ts @@ -1,6 +1,6 @@ import { useMemo } from 'react'; +import { useSetting } from '@rocket.chat/ui-contexts'; -import { useSetting } from '../../../../client/contexts/SettingsContext'; import { addAction } from '../../../../client/views/room/lib/Toolbox'; addAction('omnichannel-external-frame', () => { diff --git a/apps/meteor/app/livestream/client/tabBar.tsx b/apps/meteor/app/livestream/client/tabBar.tsx index 7305f3a87056..d06e2ee90aa6 100644 --- a/apps/meteor/app/livestream/client/tabBar.tsx +++ b/apps/meteor/app/livestream/client/tabBar.tsx @@ -1,8 +1,7 @@ import React, { ReactNode, useMemo } from 'react'; import { Option, Badge } from '@rocket.chat/fuselage'; +import { useSetting, useTranslation } from '@rocket.chat/ui-contexts'; -import { useSetting } from '../../../client/contexts/SettingsContext'; -import { useTranslation } from '../../../client/contexts/TranslationContext'; import { addAction } from '../../../client/views/room/lib/Toolbox'; import Header from '../../../client/components/Header'; diff --git a/apps/meteor/app/mail-messages/client/index.ts b/apps/meteor/app/mail-messages/client/index.ts deleted file mode 100644 index 8ad6156d106a..000000000000 --- a/apps/meteor/app/mail-messages/client/index.ts +++ /dev/null @@ -1 +0,0 @@ -import './startup'; diff --git a/apps/meteor/app/mail-messages/client/startup.js b/apps/meteor/app/mail-messages/client/startup.js deleted file mode 100644 index 6df18c09aa2b..000000000000 --- a/apps/meteor/app/mail-messages/client/startup.js +++ /dev/null @@ -1,9 +0,0 @@ -import { hasAllPermission } from '../../authorization'; -import { registerAdminSidebarItem } from '../../../client/views/admin'; - -registerAdminSidebarItem({ - href: 'admin-mailer', - i18nLabel: 'Mailer', - icon: 'mail', - permissionGranted: () => hasAllPermission('access-mailer'), -}); diff --git a/apps/meteor/app/message-pin/client/tabBar.ts b/apps/meteor/app/message-pin/client/tabBar.ts index 9b0f978f45c3..a5b5242d83b2 100644 --- a/apps/meteor/app/message-pin/client/tabBar.ts +++ b/apps/meteor/app/message-pin/client/tabBar.ts @@ -1,7 +1,7 @@ import { useMemo } from 'react'; +import { useSetting } from '@rocket.chat/ui-contexts'; import { addAction } from '../../../client/views/room/lib/Toolbox'; -import { useSetting } from '../../../client/contexts/SettingsContext'; addAction('pinned-messages', () => { const pinningAllowed = useSetting('Message_AllowPinning'); diff --git a/apps/meteor/app/message-snippet/client/tabBar/tabBar.ts b/apps/meteor/app/message-snippet/client/tabBar/tabBar.ts index 1416a2ef2c2a..6e36a47833a8 100644 --- a/apps/meteor/app/message-snippet/client/tabBar/tabBar.ts +++ b/apps/meteor/app/message-snippet/client/tabBar/tabBar.ts @@ -1,7 +1,7 @@ import { useMemo } from 'react'; +import { useSetting } from '@rocket.chat/ui-contexts'; import { addAction } from '../../../../client/views/room/lib/Toolbox'; -import { useSetting } from '../../../../client/contexts/SettingsContext'; addAction('snippeted-messages', () => { const snippetingEnabled = useSetting('Message_AllowSnippeting'); diff --git a/apps/meteor/app/oauth2-server-config/client/admin/startup.js b/apps/meteor/app/oauth2-server-config/client/admin/startup.js deleted file mode 100644 index 39f8266a7b9a..000000000000 --- a/apps/meteor/app/oauth2-server-config/client/admin/startup.js +++ /dev/null @@ -1,11 +0,0 @@ -import { hasAllPermission } from '../../../authorization'; -import { registerAdminSidebarItem } from '../../../../client/views/admin'; - -registerAdminSidebarItem({ - href: 'admin-oauth-apps', - i18nLabel: 'OAuth Apps', - icon: 'discover', - permissionGranted() { - return hasAllPermission('manage-oauth-apps'); - }, -}); diff --git a/apps/meteor/app/oauth2-server-config/client/index.js b/apps/meteor/app/oauth2-server-config/client/index.js index 5911484bf1c4..17dd1b333b86 100644 --- a/apps/meteor/app/oauth2-server-config/client/index.js +++ b/apps/meteor/app/oauth2-server-config/client/index.js @@ -1,4 +1,3 @@ import './oauth/oauth2-client.html'; import './oauth/oauth2-client'; -import './admin/startup'; import './oauth/stylesheets/oauth2.css'; diff --git a/apps/meteor/app/otr/client/tabBar.ts b/apps/meteor/app/otr/client/tabBar.ts index 213aaf78980d..d3234636e344 100644 --- a/apps/meteor/app/otr/client/tabBar.ts +++ b/apps/meteor/app/otr/client/tabBar.ts @@ -1,7 +1,7 @@ import { useMemo, lazy, useEffect } from 'react'; +import { useSetting } from '@rocket.chat/ui-contexts'; import { OTR } from './rocketchat.otr'; -import { useSetting } from '../../../client/contexts/SettingsContext'; import { addAction } from '../../../client/views/room/lib/Toolbox'; const template = lazy(() => import('../../../client/views/room/contextualBar/OTR')); diff --git a/apps/meteor/app/push-notifications/client/tabBar.ts b/apps/meteor/app/push-notifications/client/tabBar.ts index bdbb64a27498..1312018a1cde 100644 --- a/apps/meteor/app/push-notifications/client/tabBar.ts +++ b/apps/meteor/app/push-notifications/client/tabBar.ts @@ -1,6 +1,6 @@ import { lazy, useMemo } from 'react'; +import { useUserSubscription } from '@rocket.chat/ui-contexts'; -import { useUserSubscription } from '../../../client/contexts/UserContext'; import { addAction } from '../../../client/views/room/lib/Toolbox'; addAction('push-notifications', ({ room }) => { diff --git a/apps/meteor/app/threads/client/flextab/threadlist.tsx b/apps/meteor/app/threads/client/flextab/threadlist.tsx index f00eeb46991d..52e8930b159c 100644 --- a/apps/meteor/app/threads/client/flextab/threadlist.tsx +++ b/apps/meteor/app/threads/client/flextab/threadlist.tsx @@ -1,9 +1,9 @@ import React, { useMemo, lazy, LazyExoticComponent, FC, ReactNode } from 'react'; import { BadgeProps } from '@rocket.chat/fuselage'; import type { ISubscription } from '@rocket.chat/core-typings'; +import { useSetting } from '@rocket.chat/ui-contexts'; import { addAction } from '../../../../client/views/room/lib/Toolbox'; -import { useSetting } from '../../../../client/contexts/SettingsContext'; import Header from '../../../../client/components/Header'; const getVariant = (tunreadUser: number, tunreadGroup: number): BadgeProps['variant'] => { diff --git a/apps/meteor/app/ui-clean-history/client/lib/tabBar.ts b/apps/meteor/app/ui-clean-history/client/lib/tabBar.ts index e1adc91d12df..fdbe64940ff3 100644 --- a/apps/meteor/app/ui-clean-history/client/lib/tabBar.ts +++ b/apps/meteor/app/ui-clean-history/client/lib/tabBar.ts @@ -1,7 +1,7 @@ import { useMemo, lazy } from 'react'; +import { usePermission } from '@rocket.chat/ui-contexts'; import { addAction } from '../../../../client/views/room/lib/Toolbox'; -import { usePermission } from '../../../../client/contexts/AuthorizationContext'; const template = lazy(() => import('../../../../client/views/room/contextualBar/PruneMessages')); diff --git a/apps/meteor/app/ui-utils/client/lib/AccountBox.d.ts b/apps/meteor/app/ui-utils/client/lib/AccountBox.d.ts index f3e32ce7ddf7..30790cd88564 100644 --- a/apps/meteor/app/ui-utils/client/lib/AccountBox.d.ts +++ b/apps/meteor/app/ui-utils/client/lib/AccountBox.d.ts @@ -1,8 +1,7 @@ import type { ComponentProps } from 'react'; import { Option } from '@rocket.chat/fuselage'; import type { IUser } from '@rocket.chat/core-typings'; - -import { TranslationKey } from '../../../../client/contexts/TranslationContext'; +import { TranslationKey } from '@rocket.chat/ui-contexts'; export declare const AccountBox: { setStatus: (status: IUser['status'], statusText?: IUser['statusText']) => void; diff --git a/apps/meteor/app/ui-utils/client/lib/MessageAction.ts b/apps/meteor/app/ui-utils/client/lib/MessageAction.ts index 703af64a903c..28cf22684bf2 100644 --- a/apps/meteor/app/ui-utils/client/lib/MessageAction.ts +++ b/apps/meteor/app/ui-utils/client/lib/MessageAction.ts @@ -6,11 +6,11 @@ import { ReactiveVar } from 'meteor/reactive-var'; import { Tracker } from 'meteor/tracker'; import { Icon } from '@rocket.chat/fuselage'; import { IMessage, IUser, ISubscription, IRoom, SettingValue } from '@rocket.chat/core-typings'; +import { TranslationKey } from '@rocket.chat/ui-contexts'; import { Messages, Rooms, Subscriptions } from '../../../models/client'; import { roomCoordinator } from '../../../../client/lib/rooms/roomCoordinator'; import { ToolboxContextValue } from '../../../../client/views/room/lib/Toolbox/ToolboxContext'; -import { TranslationKey } from '../../../../client/contexts/TranslationContext'; const call = (method: string, ...args: any[]): Promise => new Promise((resolve, reject) => { diff --git a/apps/meteor/app/ui-utils/lib/MessageTypes.ts b/apps/meteor/app/ui-utils/lib/MessageTypes.ts index 29f051a16b8c..d7d4d8e3c98d 100644 --- a/apps/meteor/app/ui-utils/lib/MessageTypes.ts +++ b/apps/meteor/app/ui-utils/lib/MessageTypes.ts @@ -1,6 +1,5 @@ import { IMessage, MessageTypesValues } from '@rocket.chat/core-typings'; - -import { TranslationKey } from '../../../client/contexts/TranslationContext'; +import { TranslationKey } from '@rocket.chat/ui-contexts'; export type MessageType = { id: MessageTypesValues; diff --git a/apps/meteor/app/user-status/client/admin/startup.js b/apps/meteor/app/user-status/client/admin/startup.js deleted file mode 100644 index 049ac2c1a61a..000000000000 --- a/apps/meteor/app/user-status/client/admin/startup.js +++ /dev/null @@ -1,11 +0,0 @@ -import { hasAtLeastOnePermission } from '../../../authorization'; -import { registerAdminSidebarItem } from '../../../../client/views/admin'; - -registerAdminSidebarItem({ - href: 'custom-user-status', - i18nLabel: 'Custom_User_Status', - icon: 'user', - permissionGranted() { - return hasAtLeastOnePermission(['manage-user-status']); - }, -}); diff --git a/apps/meteor/app/user-status/client/index.js b/apps/meteor/app/user-status/client/index.js index ecada9a17f9f..221a2decfc0b 100644 --- a/apps/meteor/app/user-status/client/index.js +++ b/apps/meteor/app/user-status/client/index.js @@ -1,5 +1,3 @@ -import './admin/startup'; - import './notifications/deleteCustomUserStatus'; import './notifications/updateCustomUserStatus'; diff --git a/apps/meteor/app/videobridge/client/tabBar.tsx b/apps/meteor/app/videobridge/client/tabBar.tsx index c3470599243b..06f85ca80614 100644 --- a/apps/meteor/app/videobridge/client/tabBar.tsx +++ b/apps/meteor/app/videobridge/client/tabBar.tsx @@ -1,13 +1,13 @@ import React, { useMemo, lazy, ReactNode } from 'react'; import { useStableArray } from '@rocket.chat/fuselage-hooks'; import { Option, Badge } from '@rocket.chat/fuselage'; +import { useUser, useSetting, useTranslation } from '@rocket.chat/ui-contexts'; -import { useSetting } from '../../../client/contexts/SettingsContext'; import { addAction, ToolboxActionConfig } from '../../../client/views/room/lib/Toolbox'; -import { useTranslation } from '../../../client/contexts/TranslationContext'; -import { useUser } from '../../../client/contexts/UserContext'; import Header from '../../../client/components/Header'; +const templateBBB = lazy(() => import('../../../client/views/room/contextualBar/VideoConference/BBB')); + addAction('bbb_video', ({ room }) => { const enabled = useSetting('bigbluebutton_Enabled'); const t = useTranslation(); @@ -28,8 +28,6 @@ addAction('bbb_video', ({ room }) => { const username = user ? user.username : ''; const enableOption = enabled && (!username || !room.muted?.includes(username)); - const templateBBB = lazy(() => import('../../../client/views/room/contextualBar/VideoConference/BBB')); - return useMemo( () => enableOption diff --git a/apps/meteor/app/webrtc/client/tabBar.tsx b/apps/meteor/app/webrtc/client/tabBar.tsx index 15305db33070..13f5ff1e0329 100644 --- a/apps/meteor/app/webrtc/client/tabBar.tsx +++ b/apps/meteor/app/webrtc/client/tabBar.tsx @@ -1,6 +1,6 @@ import { useMemo, useCallback } from 'react'; +import { useSetting } from '@rocket.chat/ui-contexts'; -import { useSetting } from '../../../client/contexts/SettingsContext'; import { addAction } from '../../../client/views/room/lib/Toolbox'; import { APIClient } from '../../utils/client'; diff --git a/apps/meteor/client/UIKit/hooks/useUIKitHandleAction.tsx b/apps/meteor/client/UIKit/hooks/useUIKitHandleAction.tsx index 1268932f65ff..b23a0b76e223 100644 --- a/apps/meteor/client/UIKit/hooks/useUIKitHandleAction.tsx +++ b/apps/meteor/client/UIKit/hooks/useUIKitHandleAction.tsx @@ -7,7 +7,7 @@ import { UiKitPayload, UIKitActionEvent } from '@rocket.chat/core-typings'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; // import { UIKitIncomingInteractionContainerType } from '@rocket.chat/apps-engine/definition/uikit/UIKitIncomingInteractionContainer'; -// import { useEndpoint } from '../../contexts/ServerContext'; +// import { useEndpoint } from '@rocket.chat/ui-contexts'; import * as ActionManager from '../../../app/ui-message/client/ActionManager'; const useUIKitHandleAction = (state: S): ((event: UIKitActionEvent) => Promise) => diff --git a/apps/meteor/client/UIKit/hooks/useUIKitHandleClose.tsx b/apps/meteor/client/UIKit/hooks/useUIKitHandleClose.tsx index c24d0758c899..5bd5838f5fc0 100644 --- a/apps/meteor/client/UIKit/hooks/useUIKitHandleClose.tsx +++ b/apps/meteor/client/UIKit/hooks/useUIKitHandleClose.tsx @@ -5,11 +5,12 @@ import { UIKitInteractionType } from '@rocket.chat/apps-engine/definition/uikit' // import React, { Context, FC, useMemo } from 'react'; import { UiKitPayload } from '@rocket.chat/core-typings'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useToastMessageDispatch } from '@rocket.chat/ui-contexts'; // import { UIKitIncomingInteractionContainerType } from '@rocket.chat/apps-engine/definition/uikit/UIKitIncomingInteractionContainer'; -// import { useEndpoint } from '../../contexts/ServerContext'; +// import { useEndpoint } from '@rocket.chat/ui-contexts'; + import * as ActionManager from '../../../app/ui-message/client/ActionManager'; -import { useToastMessageDispatch } from '../../contexts/ToastMessagesContext'; // eslint-disable-next-line @typescript-eslint/no-unused-vars const emptyFn = (_error: any, _result: UIKitInteractionType | void): void => undefined; diff --git a/apps/meteor/client/components/AutoCompleteDepartment.js b/apps/meteor/client/components/AutoCompleteDepartment.js index c67e2b068808..fb9ed3a48ecb 100644 --- a/apps/meteor/client/components/AutoCompleteDepartment.js +++ b/apps/meteor/client/components/AutoCompleteDepartment.js @@ -3,9 +3,9 @@ // fuselage release is OoS of this regression import { PaginatedSelectFiltered } from '@rocket.chat/fuselage'; import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { memo, useMemo, useState } from 'react'; -import { useTranslation } from '../contexts/TranslationContext'; import { useRecordList } from '../hooks/lists/useRecordList'; import { AsyncStatePhase } from '../hooks/useAsyncState'; import { useDepartmentsList } from './Omnichannel/hooks/useDepartmentsList'; diff --git a/apps/meteor/client/components/AutoCompleteDepartmentMultiple.js b/apps/meteor/client/components/AutoCompleteDepartmentMultiple.js index 467eeba0bab9..0ccbab0e0c21 100644 --- a/apps/meteor/client/components/AutoCompleteDepartmentMultiple.js +++ b/apps/meteor/client/components/AutoCompleteDepartmentMultiple.js @@ -1,8 +1,8 @@ import { PaginatedMultiSelectFiltered } from '@rocket.chat/fuselage'; import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { memo, useMemo, useState } from 'react'; -import { useTranslation } from '../contexts/TranslationContext'; import { useRecordList } from '../hooks/lists/useRecordList'; import { AsyncStatePhase } from '../hooks/useAsyncState'; import { useDepartmentsList } from './Omnichannel/hooks/useDepartmentsList'; diff --git a/apps/meteor/client/components/BurgerMenu/BurgerMenu.tsx b/apps/meteor/client/components/BurgerMenu/BurgerMenu.tsx index 785f943282c6..aca62a4578a6 100644 --- a/apps/meteor/client/components/BurgerMenu/BurgerMenu.tsx +++ b/apps/meteor/client/components/BurgerMenu/BurgerMenu.tsx @@ -1,8 +1,7 @@ import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useLayout, useSession } from '@rocket.chat/ui-contexts'; import React, { memo, ReactElement } from 'react'; -import { useLayout } from '../../contexts/LayoutContext'; -import { useSession } from '../../contexts/SessionContext'; import { useEmbeddedLayout } from '../../hooks/useEmbeddedLayout'; import BurgerMenuButton from './BurgerMenuButton'; diff --git a/apps/meteor/client/components/BurgerMenu/BurgerMenuButton.tsx b/apps/meteor/client/components/BurgerMenu/BurgerMenuButton.tsx index a92c368489be..53c923f9a4df 100644 --- a/apps/meteor/client/components/BurgerMenu/BurgerMenuButton.tsx +++ b/apps/meteor/client/components/BurgerMenu/BurgerMenuButton.tsx @@ -1,8 +1,8 @@ import { css } from '@rocket.chat/css-in-js'; import { Box } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement } from 'react'; -import { useTranslation } from '../../contexts/TranslationContext'; import BurgerBadge from './BurgerBadge'; import BurgerIcon from './BurgerIcon'; diff --git a/apps/meteor/client/components/ConfirmOwnerChangeWarningModal.tsx b/apps/meteor/client/components/ConfirmOwnerChangeWarningModal.tsx index c981a9819d0a..694ca1b9905c 100644 --- a/apps/meteor/client/components/ConfirmOwnerChangeWarningModal.tsx +++ b/apps/meteor/client/components/ConfirmOwnerChangeWarningModal.tsx @@ -1,7 +1,7 @@ import { Box } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; -import { useTranslation } from '../contexts/TranslationContext'; import GenericModal from './GenericModal'; import RawText from './RawText'; diff --git a/apps/meteor/client/components/CreateDiscussion/CreateDiscussion.tsx b/apps/meteor/client/components/CreateDiscussion/CreateDiscussion.tsx index 9609f1ba118d..0b684b4d1488 100644 --- a/apps/meteor/client/components/CreateDiscussion/CreateDiscussion.tsx +++ b/apps/meteor/client/components/CreateDiscussion/CreateDiscussion.tsx @@ -1,9 +1,9 @@ import type { IMessage, IRoom, IUser } from '@rocket.chat/core-typings'; import { Modal, Field, FieldGroup, ToggleSwitch, TextInput, TextAreaInput, ButtonGroup, Button, Icon, Box } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement } from 'react'; -import { useTranslation } from '../../contexts/TranslationContext'; import { useEndpointActionExperimental } from '../../hooks/useEndpointActionExperimental'; import { useForm } from '../../hooks/useForm'; import { goToRoomById } from '../../lib/utils/goToRoomById'; diff --git a/apps/meteor/client/components/CreateDiscussion/DefaultParentRoomField.tsx b/apps/meteor/client/components/CreateDiscussion/DefaultParentRoomField.tsx index 8c788e55128c..bdbb32108457 100644 --- a/apps/meteor/client/components/CreateDiscussion/DefaultParentRoomField.tsx +++ b/apps/meteor/client/components/CreateDiscussion/DefaultParentRoomField.tsx @@ -1,7 +1,7 @@ import { Skeleton, TextInput, Callout } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { useMemo, ReactElement } from 'react'; -import { useTranslation } from '../../contexts/TranslationContext'; import { AsyncStatePhase } from '../../hooks/useAsyncState'; import { useEndpointData } from '../../hooks/useEndpointData'; import { roomCoordinator } from '../../lib/rooms/roomCoordinator'; diff --git a/apps/meteor/client/components/CustomFieldsForm.js b/apps/meteor/client/components/CustomFieldsForm.js index db7d410f11d3..9fdb06bab816 100644 --- a/apps/meteor/client/components/CustomFieldsForm.js +++ b/apps/meteor/client/components/CustomFieldsForm.js @@ -1,9 +1,8 @@ import { TextInput, Select, Field } from '@rocket.chat/fuselage'; import { capitalize } from '@rocket.chat/string-helpers'; +import { useSetting, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useMemo, useEffect, useState } from 'react'; -import { useSetting } from '../contexts/SettingsContext'; -import { useTranslation } from '../contexts/TranslationContext'; import { useComponentDidUpdate } from '../hooks/useComponentDidUpdate'; import { useForm } from '../hooks/useForm'; diff --git a/apps/meteor/client/components/FilterByText.tsx b/apps/meteor/client/components/FilterByText.tsx index 04abdd00a0a8..d75050a57843 100644 --- a/apps/meteor/client/components/FilterByText.tsx +++ b/apps/meteor/client/components/FilterByText.tsx @@ -1,8 +1,7 @@ import { Box, Icon, TextInput, Button } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC, ChangeEvent, FormEvent, memo, useCallback, useEffect, useState } from 'react'; -import { useTranslation } from '../contexts/TranslationContext'; - type FilterByTextProps = { placeholder?: string; onChange: (filter: { text: string }) => void; diff --git a/apps/meteor/client/components/GenericModal.tsx b/apps/meteor/client/components/GenericModal.tsx index 1ae3eabd6d46..afd8467aee08 100644 --- a/apps/meteor/client/components/GenericModal.tsx +++ b/apps/meteor/client/components/GenericModal.tsx @@ -1,7 +1,7 @@ import { Box, Button, ButtonGroup, Icon, Modal } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC, ComponentProps, ReactElement, ReactNode } from 'react'; -import { useTranslation } from '../contexts/TranslationContext'; import { withDoNotAskAgain, RequiredModalProps } from './withDoNotAskAgain'; type VariantType = 'danger' | 'warning' | 'info' | 'success'; diff --git a/apps/meteor/client/components/GenericTable/GenericTable.tsx b/apps/meteor/client/components/GenericTable/GenericTable.tsx index 06781fed7431..588c3cd6be40 100644 --- a/apps/meteor/client/components/GenericTable/GenericTable.tsx +++ b/apps/meteor/client/components/GenericTable/GenericTable.tsx @@ -1,9 +1,9 @@ import { Pagination, Tile } from '@rocket.chat/fuselage'; import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { useState, useEffect, forwardRef, ReactNode, ReactElement, Key, useMemo, Ref } from 'react'; import flattenChildren from 'react-keyed-flatten-children'; -import { useTranslation } from '../../contexts/TranslationContext'; import { GenericTable as GenericTableV2 } from './V2/GenericTable'; import { GenericTableBody } from './V2/GenericTableBody'; import { GenericTableHeader } from './V2/GenericTableHeader'; diff --git a/apps/meteor/client/components/GenericTable/hooks/useItemsPerPageLabel.ts b/apps/meteor/client/components/GenericTable/hooks/useItemsPerPageLabel.ts index 79e65d88f370..0a8a8deb8262 100644 --- a/apps/meteor/client/components/GenericTable/hooks/useItemsPerPageLabel.ts +++ b/apps/meteor/client/components/GenericTable/hooks/useItemsPerPageLabel.ts @@ -1,7 +1,6 @@ +import { useTranslation } from '@rocket.chat/ui-contexts'; import { useCallback } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; - export const useItemsPerPageLabel = (): (() => string) => { const t = useTranslation(); return useCallback(() => t('Items_per_page:'), [t]); diff --git a/apps/meteor/client/components/GenericTable/hooks/useShowingResultsLabel.ts b/apps/meteor/client/components/GenericTable/hooks/useShowingResultsLabel.ts index 030929bb5bdd..4a4e2b3c0236 100644 --- a/apps/meteor/client/components/GenericTable/hooks/useShowingResultsLabel.ts +++ b/apps/meteor/client/components/GenericTable/hooks/useShowingResultsLabel.ts @@ -1,8 +1,7 @@ import { Pagination } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import { ComponentProps, useCallback } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; - type Props['showingResultsLabel'] = ComponentProps['showingResultsLabel']> = T extends (...args: any[]) => any ? Parameters : never; diff --git a/apps/meteor/client/components/Header/Header.stories.tsx b/apps/meteor/client/components/Header/Header.stories.tsx index c199eff25893..0f7905c3d0a6 100644 --- a/apps/meteor/client/components/Header/Header.stories.tsx +++ b/apps/meteor/client/components/Header/Header.stories.tsx @@ -1,10 +1,10 @@ import type { IRoom } from '@rocket.chat/core-typings'; +import { SettingsContext } from '@rocket.chat/ui-contexts'; import { action } from '@storybook/addon-actions'; import { ComponentMeta, ComponentStory } from '@storybook/react'; import React from 'react'; import Header from '.'; -import { SettingsContext } from '../../contexts/SettingsContext'; import { useRoomIcon } from '../../hooks/useRoomIcon'; import ToolBox from '../../views/room/Header/ToolBox'; import { ActionRenderer, addAction } from '../../views/room/lib/Toolbox'; diff --git a/apps/meteor/client/components/Header/Header.tsx b/apps/meteor/client/components/Header/Header.tsx index 9c14618c44b3..c9c33e2ddaf1 100644 --- a/apps/meteor/client/components/Header/Header.tsx +++ b/apps/meteor/client/components/Header/Header.tsx @@ -1,7 +1,7 @@ import { Box } from '@rocket.chat/fuselage'; +import { useLayout } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; -import { useLayout } from '../../contexts/LayoutContext'; import HeaderDivider from './HeaderDivider'; const Header: FC = (props) => { diff --git a/apps/meteor/client/components/LocalTime.tsx b/apps/meteor/client/components/LocalTime.tsx index bb2ccec35554..d4953717e010 100644 --- a/apps/meteor/client/components/LocalTime.tsx +++ b/apps/meteor/client/components/LocalTime.tsx @@ -1,6 +1,6 @@ +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { memo, ReactElement } from 'react'; -import { useTranslation } from '../contexts/TranslationContext'; import { useUTCClock } from '../hooks/useUTCClock'; type LocalTimeProps = { diff --git a/apps/meteor/client/components/Message/Attachments/Attachment/Attachment.tsx b/apps/meteor/client/components/Message/Attachments/Attachment/Attachment.tsx index 2de670483b9d..f7d5bcdce81d 100644 --- a/apps/meteor/client/components/Message/Attachments/Attachment/Attachment.tsx +++ b/apps/meteor/client/components/Message/Attachments/Attachment/Attachment.tsx @@ -1,8 +1,7 @@ import { Box } from '@rocket.chat/fuselage'; +import { useAttachmentDimensions } from '@rocket.chat/ui-contexts'; import React, { ComponentProps, FC } from 'react'; -import { useAttachmentDimensions } from '../context/AttachmentContext'; - const Attachment: FC> = (props) => { const { width } = useAttachmentDimensions(); return ( diff --git a/apps/meteor/client/components/Message/Attachments/Attachment/Collapse.tsx b/apps/meteor/client/components/Message/Attachments/Attachment/Collapse.tsx index 21cfc6309b33..dd1477d157cb 100644 --- a/apps/meteor/client/components/Message/Attachments/Attachment/Collapse.tsx +++ b/apps/meteor/client/components/Message/Attachments/Attachment/Collapse.tsx @@ -1,6 +1,6 @@ +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { ComponentProps, FC } from 'react'; -import { useTranslation } from '../../../../contexts/TranslationContext'; import Action from './Action'; const Collapse: FC, 'icon'> & { collapsed?: boolean }> = ({ collapsed = false, ...props }) => { diff --git a/apps/meteor/client/components/Message/Attachments/Attachment/Download.tsx b/apps/meteor/client/components/Message/Attachments/Attachment/Download.tsx index c88d6d840ed8..1d2b46fb2f23 100644 --- a/apps/meteor/client/components/Message/Attachments/Attachment/Download.tsx +++ b/apps/meteor/client/components/Message/Attachments/Attachment/Download.tsx @@ -1,6 +1,6 @@ +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { ComponentProps, FC } from 'react'; -import { useTranslation } from '../../../../contexts/TranslationContext'; import Action from './Action'; const Download: FC, 'icon'> & { title?: string | undefined; href: string }> = ({ diff --git a/apps/meteor/client/components/Message/Attachments/Files/AudioAttachment.tsx b/apps/meteor/client/components/Message/Attachments/Files/AudioAttachment.tsx index 6e7450cc51ce..771042e517aa 100644 --- a/apps/meteor/client/components/Message/Attachments/Files/AudioAttachment.tsx +++ b/apps/meteor/client/components/Message/Attachments/Files/AudioAttachment.tsx @@ -1,9 +1,9 @@ import { AudioAttachmentProps } from '@rocket.chat/core-typings'; +import { useMediaUrl } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; import MarkdownText from '../../../MarkdownText'; import Attachment from '../Attachment'; -import { useMediaUrl } from '../context/AttachmentContext'; import { useCollapse } from '../hooks/useCollapse'; export const AudioAttachment: FC = ({ diff --git a/apps/meteor/client/components/Message/Attachments/Files/GenericFileAttachment.tsx b/apps/meteor/client/components/Message/Attachments/Files/GenericFileAttachment.tsx index 2cb6c95ab25f..bb571a379a29 100644 --- a/apps/meteor/client/components/Message/Attachments/Files/GenericFileAttachment.tsx +++ b/apps/meteor/client/components/Message/Attachments/Files/GenericFileAttachment.tsx @@ -1,9 +1,9 @@ import { FileProp, MessageAttachmentBase } from '@rocket.chat/core-typings'; +import { useMediaUrl } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; import MarkdownText from '../../../MarkdownText'; import Attachment from '../Attachment'; -import { useMediaUrl } from '../context/AttachmentContext'; export type GenericFileAttachmentProps = { file?: FileProp; diff --git a/apps/meteor/client/components/Message/Attachments/Files/ImageAttachment.tsx b/apps/meteor/client/components/Message/Attachments/Files/ImageAttachment.tsx index 44ca6cf25705..a45a96c4b22c 100644 --- a/apps/meteor/client/components/Message/Attachments/Files/ImageAttachment.tsx +++ b/apps/meteor/client/components/Message/Attachments/Files/ImageAttachment.tsx @@ -1,10 +1,10 @@ import { ImageAttachmentProps } from '@rocket.chat/core-typings'; +import { useMediaUrl } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; import MarkdownText from '../../../MarkdownText'; import Attachment from '../Attachment'; import Image from '../components/Image'; -import { useMediaUrl } from '../context/AttachmentContext'; import { useCollapse } from '../hooks/useCollapse'; import { useLoadImage } from '../hooks/useLoadImage'; diff --git a/apps/meteor/client/components/Message/Attachments/Files/PDFAttachment.tsx b/apps/meteor/client/components/Message/Attachments/Files/PDFAttachment.tsx index 93aa27ce7120..5efedf8df273 100644 --- a/apps/meteor/client/components/Message/Attachments/Files/PDFAttachment.tsx +++ b/apps/meteor/client/components/Message/Attachments/Files/PDFAttachment.tsx @@ -1,7 +1,7 @@ import { PDFAttachmentProps } from '@rocket.chat/core-typings'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; -import { useTranslation } from '../../../../contexts/TranslationContext'; import MarkdownText from '../../../MarkdownText'; import Attachment from '../Attachment'; import { useCollapse } from '../hooks/useCollapse'; diff --git a/apps/meteor/client/components/Message/Attachments/Files/VideoAttachment.tsx b/apps/meteor/client/components/Message/Attachments/Files/VideoAttachment.tsx index 9d67035cfc2f..2205d54f5b1c 100644 --- a/apps/meteor/client/components/Message/Attachments/Files/VideoAttachment.tsx +++ b/apps/meteor/client/components/Message/Attachments/Files/VideoAttachment.tsx @@ -1,10 +1,10 @@ import { VideoAttachmentProps } from '@rocket.chat/core-typings'; import { Box } from '@rocket.chat/fuselage'; +import { useMediaUrl } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; import MarkdownText from '../../../MarkdownText'; import Attachment from '../Attachment'; -import { useMediaUrl } from '../context/AttachmentContext'; import { useCollapse } from '../hooks/useCollapse'; export const VideoAttachment: FC = ({ diff --git a/apps/meteor/client/components/Message/Attachments/components/Image.tsx b/apps/meteor/client/components/Message/Attachments/components/Image.tsx index b664b3467fef..8da784cd4f9f 100644 --- a/apps/meteor/client/components/Message/Attachments/components/Image.tsx +++ b/apps/meteor/client/components/Message/Attachments/components/Image.tsx @@ -1,7 +1,7 @@ import { Dimensions } from '@rocket.chat/core-typings'; +import { useAttachmentDimensions } from '@rocket.chat/ui-contexts'; import React, { memo, FC, useState, useMemo } from 'react'; -import { useAttachmentDimensions } from '../context/AttachmentContext'; import ImageBox from './ImageBox'; import Load from './Load'; import Retry from './Retry'; diff --git a/apps/meteor/client/components/Message/Attachments/components/Load.tsx b/apps/meteor/client/components/Message/Attachments/components/Load.tsx index 5a901efb99bc..83e38ea2a802 100644 --- a/apps/meteor/client/components/Message/Attachments/components/Load.tsx +++ b/apps/meteor/client/components/Message/Attachments/components/Load.tsx @@ -1,9 +1,9 @@ import { css } from '@rocket.chat/css-in-js'; import { Box, Icon } from '@rocket.chat/fuselage'; import colors from '@rocket.chat/fuselage-tokens/colors'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { ComponentProps, FC } from 'react'; -import { useTranslation } from '../../../../contexts/TranslationContext'; import ImageBox from './ImageBox'; type LoadProps = ComponentProps & { load: () => void }; diff --git a/apps/meteor/client/components/Message/Attachments/components/Retry.tsx b/apps/meteor/client/components/Message/Attachments/components/Retry.tsx index 3f6351295343..4359cdd35d03 100644 --- a/apps/meteor/client/components/Message/Attachments/components/Retry.tsx +++ b/apps/meteor/client/components/Message/Attachments/components/Retry.tsx @@ -1,9 +1,9 @@ import { css } from '@rocket.chat/css-in-js'; import { Box, Icon } from '@rocket.chat/fuselage'; import colors from '@rocket.chat/fuselage-tokens/colors'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC, ComponentProps } from 'react'; -import { useTranslation } from '../../../../contexts/TranslationContext'; import ImageBox from './ImageBox'; type RetryProps = ComponentProps & { retry: () => void }; diff --git a/apps/meteor/client/components/Message/Attachments/context/AttachmentContext.tsx b/apps/meteor/client/components/Message/Attachments/context/AttachmentContext.tsx deleted file mode 100644 index 8e3d4f2d7189..000000000000 --- a/apps/meteor/client/components/Message/Attachments/context/AttachmentContext.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { createContext, useContext } from 'react'; - -export type AttachmentContextValue = { - getURL: (url: string) => string; - dimensions: { - width: number; - height: number; - }; - collapsedByDefault: boolean; - autoLoadEmbedMedias: boolean; -}; - -export const AttachmentContext = createContext({ - getURL: (url: string) => url, - dimensions: { - width: 480, - height: 360, - }, - collapsedByDefault: false, - autoLoadEmbedMedias: true, -}); - -export const useMediaUrl = (): ((path: string) => string) => { - const { getURL } = useContext(AttachmentContext); - return getURL; -}; - -export const useAttachmentDimensions = (): { - width: number; - height: number; -} => useContext(AttachmentContext).dimensions; - -export const useAttachmentIsCollapsedByDefault = (): boolean => useContext(AttachmentContext).collapsedByDefault; -export const useAttachmentAutoLoadEmbedMedia = (): boolean => useContext(AttachmentContext).autoLoadEmbedMedias; diff --git a/apps/meteor/client/components/Message/Attachments/hooks/useCollapse.tsx b/apps/meteor/client/components/Message/Attachments/hooks/useCollapse.tsx index 09911f68788f..5f320a87480d 100644 --- a/apps/meteor/client/components/Message/Attachments/hooks/useCollapse.tsx +++ b/apps/meteor/client/components/Message/Attachments/hooks/useCollapse.tsx @@ -1,8 +1,8 @@ import { useToggle } from '@rocket.chat/fuselage-hooks'; +import { useAttachmentIsCollapsedByDefault } from '@rocket.chat/ui-contexts'; import React from 'react'; import Attachment from '../Attachment'; -import { useAttachmentIsCollapsedByDefault } from '../context/AttachmentContext'; export const useCollapse = (attachmentCollapsed: boolean): [boolean, JSX.Element] => { const collpaseByDefault = useAttachmentIsCollapsedByDefault(); diff --git a/apps/meteor/client/components/Message/Attachments/hooks/useLoadImage.tsx b/apps/meteor/client/components/Message/Attachments/hooks/useLoadImage.tsx index e9e803afc99e..83a4fff5e181 100644 --- a/apps/meteor/client/components/Message/Attachments/hooks/useLoadImage.tsx +++ b/apps/meteor/client/components/Message/Attachments/hooks/useLoadImage.tsx @@ -1,7 +1,6 @@ +import { useAttachmentAutoLoadEmbedMedia } from '@rocket.chat/ui-contexts'; import { useCallback, useState } from 'react'; -import { useAttachmentAutoLoadEmbedMedia } from '../context/AttachmentContext'; - export const useLoadImage = (): [boolean, () => void] => { const [loadImage, setLoadImage] = useState(useAttachmentAutoLoadEmbedMedia()); return [loadImage, useCallback(() => setLoadImage(true), [])]; diff --git a/apps/meteor/client/components/Message/Attachments/providers/AttachmentProvider.tsx b/apps/meteor/client/components/Message/Attachments/providers/AttachmentProvider.tsx index df43e66c9c55..a287017b85bb 100644 --- a/apps/meteor/client/components/Message/Attachments/providers/AttachmentProvider.tsx +++ b/apps/meteor/client/components/Message/Attachments/providers/AttachmentProvider.tsx @@ -1,10 +1,8 @@ import { usePrefersReducedData } from '@rocket.chat/fuselage-hooks'; +import { AttachmentContext, AttachmentContextValue, useLayout, useUserPreference } from '@rocket.chat/ui-contexts'; import React, { useMemo, FC } from 'react'; import { getURL } from '../../../../../app/utils/client'; -import { useLayout } from '../../../../contexts/LayoutContext'; -import { useUserPreference } from '../../../../contexts/UserContext'; -import { AttachmentContext, AttachmentContextValue } from '../context/AttachmentContext'; const AttachmentProvider: FC = ({ children }) => { const { isMobile } = useLayout(); diff --git a/apps/meteor/client/components/Message/MessageActions/Action.tsx b/apps/meteor/client/components/Message/MessageActions/Action.tsx index 38706446305d..942ab68c0b5e 100644 --- a/apps/meteor/client/components/Message/MessageActions/Action.tsx +++ b/apps/meteor/client/components/Message/MessageActions/Action.tsx @@ -1,8 +1,7 @@ import { IconProps, Icon, Button } from '@rocket.chat/fuselage'; +import { TranslationKey, useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; -import { TranslationKey, useTranslation } from '../../../contexts/TranslationContext'; - type RunAction = (action: string) => () => void; type ActionOptions = { diff --git a/apps/meteor/client/components/Message/MessageActions/Actions.tsx b/apps/meteor/client/components/Message/MessageActions/Actions.tsx index f5d88ab21ed2..bf9c27674cb9 100644 --- a/apps/meteor/client/components/Message/MessageActions/Actions.tsx +++ b/apps/meteor/client/components/Message/MessageActions/Actions.tsx @@ -1,7 +1,7 @@ import { IconProps, ButtonGroup } from '@rocket.chat/fuselage'; +import { TranslationKey } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; -import { TranslationKey } from '../../../contexts/TranslationContext'; import Content from '../Metrics/Content'; import Action from './Action'; diff --git a/apps/meteor/client/components/Message/MessageBodyRender/Mention.tsx b/apps/meteor/client/components/Message/MessageBodyRender/Mention.tsx index 5a660bca8c47..b1a539e24cbe 100644 --- a/apps/meteor/client/components/Message/MessageBodyRender/Mention.tsx +++ b/apps/meteor/client/components/Message/MessageBodyRender/Mention.tsx @@ -1,7 +1,7 @@ import { UserMention as ASTUserMention } from '@rocket.chat/message-parser'; +import { useUserId } from '@rocket.chat/ui-contexts'; import React, { FC, memo } from 'react'; -import { useUserId } from '../../../contexts/UserContext'; import { useMessageBodyUserMentions, useMessageBodyMentionClick } from './contexts/MessageBodyContext'; const Mention: FC<{ value: ASTUserMention['value'] }> = ({ value: { value: mention } }) => { diff --git a/apps/meteor/client/components/Message/Metrics/Broadcast.tsx b/apps/meteor/client/components/Message/Metrics/Broadcast.tsx index d479dbb8755c..191de087004c 100644 --- a/apps/meteor/client/components/Message/Metrics/Broadcast.tsx +++ b/apps/meteor/client/components/Message/Metrics/Broadcast.tsx @@ -1,6 +1,6 @@ +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useBlockRendered } from '../hooks/useBlockRendered'; import Content from './Content'; import Reply from './Reply'; diff --git a/apps/meteor/client/components/Message/Metrics/Discussion.tsx b/apps/meteor/client/components/Message/Metrics/Discussion.tsx index 553b9cb67f9f..d375030f371c 100644 --- a/apps/meteor/client/components/Message/Metrics/Discussion.tsx +++ b/apps/meteor/client/components/Message/Metrics/Discussion.tsx @@ -1,7 +1,7 @@ import { Message } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useTimeAgo } from '../../../hooks/useTimeAgo'; import { useBlockRendered } from '../hooks/useBlockRendered'; diff --git a/apps/meteor/client/components/Message/Metrics/Thread.tsx b/apps/meteor/client/components/Message/Metrics/Thread.tsx index d271ebf49482..1f33834f1f2a 100644 --- a/apps/meteor/client/components/Message/Metrics/Thread.tsx +++ b/apps/meteor/client/components/Message/Metrics/Thread.tsx @@ -1,8 +1,7 @@ import { Message, MessageMetricsItem, MessageBlock } from '@rocket.chat/fuselage'; +import { useEndpoint, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback, FC, MouseEvent as ReactMouseEvent } from 'react'; -import { useEndpoint } from '../../../contexts/ServerContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useTimeAgo } from '../../../hooks/useTimeAgo'; import * as NotificationStatus from '../NotificationStatus'; import { followStyle, anchor } from '../helpers/followSyle'; diff --git a/apps/meteor/client/components/Message/NotificationStatus/NotificationStatus.tsx b/apps/meteor/client/components/Message/NotificationStatus/NotificationStatus.tsx index 0cda4e72d272..aee9f48b8e4d 100644 --- a/apps/meteor/client/components/Message/NotificationStatus/NotificationStatus.tsx +++ b/apps/meteor/client/components/Message/NotificationStatus/NotificationStatus.tsx @@ -1,8 +1,7 @@ import { Box } from '@rocket.chat/fuselage'; +import { TranslationKey, useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; -import { TranslationKey, useTranslation } from '../../../contexts/TranslationContext'; - const NotificationStatus: FC<{ label: TranslationKey; bg: string; diff --git a/apps/meteor/client/components/Omnichannel/Tags.tsx b/apps/meteor/client/components/Omnichannel/Tags.tsx index 1d315ead0913..eb4ca95ecd78 100644 --- a/apps/meteor/client/components/Omnichannel/Tags.tsx +++ b/apps/meteor/client/components/Omnichannel/Tags.tsx @@ -1,10 +1,9 @@ import { Field, TextInput, Chip, Button } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts'; import React, { ChangeEvent, ReactElement, useState } from 'react'; import { useSubscription } from 'use-subscription'; -import { useToastMessageDispatch } from '../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../contexts/TranslationContext'; import { AsyncStatePhase } from '../../hooks/useAsyncState'; import { useEndpointData } from '../../hooks/useEndpointData'; import { formsSubscription } from '../../views/omnichannel/additionalForms'; diff --git a/apps/meteor/client/components/Omnichannel/hooks/useAgentsList.ts b/apps/meteor/client/components/Omnichannel/hooks/useAgentsList.ts index d56096fd9876..c5436312abc8 100644 --- a/apps/meteor/client/components/Omnichannel/hooks/useAgentsList.ts +++ b/apps/meteor/client/components/Omnichannel/hooks/useAgentsList.ts @@ -1,8 +1,7 @@ import type { ILivechatAgent } from '@rocket.chat/core-typings'; +import { useEndpoint, useTranslation } from '@rocket.chat/ui-contexts'; import { useCallback, useState } from 'react'; -import { useEndpoint } from '../../../contexts/ServerContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useScrollableRecordList } from '../../../hooks/lists/useScrollableRecordList'; import { useComponentDidUpdate } from '../../../hooks/useComponentDidUpdate'; import { RecordList } from '../../../lib/lists/RecordList'; diff --git a/apps/meteor/client/components/Omnichannel/hooks/useAvailableAgentsList.ts b/apps/meteor/client/components/Omnichannel/hooks/useAvailableAgentsList.ts index 76520fe36e42..d0c2db186100 100644 --- a/apps/meteor/client/components/Omnichannel/hooks/useAvailableAgentsList.ts +++ b/apps/meteor/client/components/Omnichannel/hooks/useAvailableAgentsList.ts @@ -1,7 +1,7 @@ import type { ILivechatAgent } from '@rocket.chat/core-typings'; +import { useEndpoint } from '@rocket.chat/ui-contexts'; import { useCallback, useState } from 'react'; -import { useEndpoint } from '../../../contexts/ServerContext'; import { useScrollableRecordList } from '../../../hooks/lists/useScrollableRecordList'; import { useComponentDidUpdate } from '../../../hooks/useComponentDidUpdate'; import { RecordList } from '../../../lib/lists/RecordList'; diff --git a/apps/meteor/client/components/Omnichannel/hooks/useDepartmentsList.ts b/apps/meteor/client/components/Omnichannel/hooks/useDepartmentsList.ts index e9ecc3d41520..a80ea72447ab 100644 --- a/apps/meteor/client/components/Omnichannel/hooks/useDepartmentsList.ts +++ b/apps/meteor/client/components/Omnichannel/hooks/useDepartmentsList.ts @@ -1,8 +1,7 @@ import type { ILivechatDepartmentRecord } from '@rocket.chat/core-typings'; +import { useEndpoint, useTranslation } from '@rocket.chat/ui-contexts'; import { useCallback, useState } from 'react'; -import { useEndpoint } from '../../../contexts/ServerContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useScrollableRecordList } from '../../../hooks/lists/useScrollableRecordList'; import { useComponentDidUpdate } from '../../../hooks/useComponentDidUpdate'; import { RecordList } from '../../../lib/lists/RecordList'; diff --git a/apps/meteor/client/components/Omnichannel/modals/CloseChatModal.tsx b/apps/meteor/client/components/Omnichannel/modals/CloseChatModal.tsx index 4493b19ea2d9..261ae721109d 100644 --- a/apps/meteor/client/components/Omnichannel/modals/CloseChatModal.tsx +++ b/apps/meteor/client/components/Omnichannel/modals/CloseChatModal.tsx @@ -1,10 +1,9 @@ import { ILivechatDepartment } from '@rocket.chat/core-typings'; import { Field, Button, TextInput, Icon, ButtonGroup, Modal, Box } from '@rocket.chat/fuselage'; +import { useSetting, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback, useState, useEffect, ReactElement, useMemo } from 'react'; import { useForm } from 'react-hook-form'; -import { useSetting } from '../../../contexts/SettingsContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import GenericModal from '../../GenericModal'; import Tags from '../Tags'; diff --git a/apps/meteor/client/components/Omnichannel/modals/ForwardChatModal.tsx b/apps/meteor/client/components/Omnichannel/modals/ForwardChatModal.tsx index 1697b0b4c31c..616895ddc771 100644 --- a/apps/meteor/client/components/Omnichannel/modals/ForwardChatModal.tsx +++ b/apps/meteor/client/components/Omnichannel/modals/ForwardChatModal.tsx @@ -1,11 +1,10 @@ import { IOmnichannelRoom } from '@rocket.chat/core-typings'; import { Field, Button, TextAreaInput, Icon, ButtonGroup, Modal, Box, PaginatedSelectFiltered } from '@rocket.chat/fuselage'; import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; +import { useEndpoint, useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement, useCallback, useEffect, useMemo, useState } from 'react'; import { useForm } from 'react-hook-form'; -import { useEndpoint } from '../../../contexts/ServerContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useRecordList } from '../../../hooks/lists/useRecordList'; import { AsyncStatePhase } from '../../../hooks/useAsyncState'; import UserAutoComplete from '../../UserAutoComplete'; diff --git a/apps/meteor/client/components/Omnichannel/modals/ReturnChatQueueModal.tsx b/apps/meteor/client/components/Omnichannel/modals/ReturnChatQueueModal.tsx index 04fe0249ef91..758295e4012f 100644 --- a/apps/meteor/client/components/Omnichannel/modals/ReturnChatQueueModal.tsx +++ b/apps/meteor/client/components/Omnichannel/modals/ReturnChatQueueModal.tsx @@ -1,8 +1,7 @@ import { Box, Button, ButtonGroup, Icon, Modal } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; - type ReturnChatQueueModalProps = { onMoveChat: () => void; onCancel: () => void; diff --git a/apps/meteor/client/components/Omnichannel/modals/TranscriptModal.tsx b/apps/meteor/client/components/Omnichannel/modals/TranscriptModal.tsx index d39d1abdd310..c25e8cc23aaa 100644 --- a/apps/meteor/client/components/Omnichannel/modals/TranscriptModal.tsx +++ b/apps/meteor/client/components/Omnichannel/modals/TranscriptModal.tsx @@ -1,9 +1,9 @@ import type { IOmnichannelRoom } from '@rocket.chat/core-typings'; import { Field, Button, TextInput, Icon, ButtonGroup, Modal } from '@rocket.chat/fuselage'; import { useAutoFocus } from '@rocket.chat/fuselage-hooks'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC, useCallback, useEffect, useState, useMemo } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useComponentDidUpdate } from '../../../hooks/useComponentDidUpdate'; import { useForm } from '../../../hooks/useForm'; diff --git a/apps/meteor/client/components/Page/PageHeader.tsx b/apps/meteor/client/components/Page/PageHeader.tsx index 8158657bcc3f..4243983d3bda 100644 --- a/apps/meteor/client/components/Page/PageHeader.tsx +++ b/apps/meteor/client/components/Page/PageHeader.tsx @@ -1,7 +1,7 @@ import { Box } from '@rocket.chat/fuselage'; +import { useLayout } from '@rocket.chat/ui-contexts'; import React, { useContext, FC, ReactNode } from 'react'; -import { useLayout } from '../../contexts/LayoutContext'; import BurgerMenu from '../BurgerMenu'; import TemplateHeader from '../Header'; import PageContext from './PageContext'; diff --git a/apps/meteor/client/components/PlanTag.tsx b/apps/meteor/client/components/PlanTag.tsx index 30e7f1993e68..4a0ad84c45cf 100644 --- a/apps/meteor/client/components/PlanTag.tsx +++ b/apps/meteor/client/components/PlanTag.tsx @@ -1,9 +1,9 @@ import { Box, Tag } from '@rocket.chat/fuselage'; import { useSafely } from '@rocket.chat/fuselage-hooks'; +import { useMethod } from '@rocket.chat/ui-contexts'; import React, { ReactElement, useEffect, useState } from 'react'; import { ILicenseTag } from '../../ee/app/license/definitions/ILicenseTag'; -import { useMethod } from '../contexts/ServerContext'; function PlanTag(): ReactElement { const [plans, setPlans] = useSafely( diff --git a/apps/meteor/client/components/RoomAutoComplete/hooks/useRoomsList.ts b/apps/meteor/client/components/RoomAutoComplete/hooks/useRoomsList.ts index 7f3c42ac5cb4..8b5cc7fbd320 100644 --- a/apps/meteor/client/components/RoomAutoComplete/hooks/useRoomsList.ts +++ b/apps/meteor/client/components/RoomAutoComplete/hooks/useRoomsList.ts @@ -1,7 +1,7 @@ import type { IRoom } from '@rocket.chat/core-typings'; +import { useEndpoint } from '@rocket.chat/ui-contexts'; import { useCallback, useState } from 'react'; -import { useEndpoint } from '../../../contexts/ServerContext'; import { useScrollableRecordList } from '../../../hooks/lists/useScrollableRecordList'; import { useComponentDidUpdate } from '../../../hooks/useComponentDidUpdate'; import { RecordList } from '../../../lib/lists/RecordList'; diff --git a/apps/meteor/client/components/RoomForeword.tsx b/apps/meteor/client/components/RoomForeword.tsx index 1d078dd08d04..3993a1ddf194 100644 --- a/apps/meteor/client/components/RoomForeword.tsx +++ b/apps/meteor/client/components/RoomForeword.tsx @@ -1,11 +1,10 @@ import { IRoom, isVoipRoom, isDirectMessageRoom } from '@rocket.chat/core-typings'; import { Avatar, Margins, Flex, Box, Tag } from '@rocket.chat/fuselage'; +import { useUser, useUserRoom, useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement } from 'react'; import { Users } from '../../app/models/client'; import { getUserAvatarURL } from '../../app/utils/client'; -import { useTranslation } from '../contexts/TranslationContext'; -import { useUser, useUserRoom } from '../contexts/UserContext'; import { VoipRoomForeword } from './voip/room/VoipRoomForeword'; type RoomForewordProps = { _id: IRoom['_id']; rid?: IRoom['_id'] } | { rid: IRoom['_id']; _id?: IRoom['_id'] }; diff --git a/apps/meteor/client/components/Sidebar/ItemsAssembler.js b/apps/meteor/client/components/Sidebar/ItemsAssembler.js index 798875bc66bb..98e64fe7e30f 100644 --- a/apps/meteor/client/components/Sidebar/ItemsAssembler.js +++ b/apps/meteor/client/components/Sidebar/ItemsAssembler.js @@ -1,6 +1,6 @@ +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { memo } from 'react'; -import { useTranslation } from '../../contexts/TranslationContext'; import Sidebar from './Sidebar'; const ItemsAssembler = ({ items, currentPath }) => { diff --git a/apps/meteor/client/components/Sidebar/NavigationItem.js b/apps/meteor/client/components/Sidebar/NavigationItem.js index c4bab5255d38..01bd0b415e0a 100644 --- a/apps/meteor/client/components/Sidebar/NavigationItem.js +++ b/apps/meteor/client/components/Sidebar/NavigationItem.js @@ -1,7 +1,7 @@ import { Box, Icon, Tag } from '@rocket.chat/fuselage'; +import { useRoutePath } from '@rocket.chat/ui-contexts'; import React, { memo, useMemo } from 'react'; -import { useRoutePath } from '../../contexts/RouterContext'; import Sidebar from './Sidebar'; const NavigationItem = ({ permissionGranted, pathGroup, pathSection, icon, label, currentPath, tag }) => { diff --git a/apps/meteor/client/components/SortList/GroupingList.tsx b/apps/meteor/client/components/SortList/GroupingList.tsx index 443e65a03792..686b61336bdd 100644 --- a/apps/meteor/client/components/SortList/GroupingList.tsx +++ b/apps/meteor/client/components/SortList/GroupingList.tsx @@ -1,9 +1,7 @@ import { CheckBox, OptionTitle } from '@rocket.chat/fuselage'; +import { useUserPreference, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback, ReactElement } from 'react'; -import { useMethod } from '../../contexts/ServerContext'; -import { useTranslation } from '../../contexts/TranslationContext'; -import { useUserPreference } from '../../contexts/UserContext'; import ListItem from '../Sidebar/ListItem'; const style = { diff --git a/apps/meteor/client/components/SortList/SortModeList.tsx b/apps/meteor/client/components/SortList/SortModeList.tsx index 2e430609d3d7..0b42a73ce5a8 100644 --- a/apps/meteor/client/components/SortList/SortModeList.tsx +++ b/apps/meteor/client/components/SortList/SortModeList.tsx @@ -1,9 +1,7 @@ import { RadioButton, OptionTitle } from '@rocket.chat/fuselage'; +import { useUserPreference, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement, useCallback } from 'react'; -import { useMethod } from '../../contexts/ServerContext'; -import { useTranslation } from '../../contexts/TranslationContext'; -import { useUserPreference } from '../../contexts/UserContext'; import ListItem from '../Sidebar/ListItem'; const style = { diff --git a/apps/meteor/client/components/SortList/ViewModeList.tsx b/apps/meteor/client/components/SortList/ViewModeList.tsx index f0dbe4751e78..617e3f123c43 100644 --- a/apps/meteor/client/components/SortList/ViewModeList.tsx +++ b/apps/meteor/client/components/SortList/ViewModeList.tsx @@ -1,9 +1,7 @@ import { ToggleSwitch, RadioButton, OptionTitle } from '@rocket.chat/fuselage'; +import { useUserPreference, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback, ReactElement } from 'react'; -import { useMethod } from '../../contexts/ServerContext'; -import { useTranslation } from '../../contexts/TranslationContext'; -import { useUserPreference } from '../../contexts/UserContext'; import ListItem from '../Sidebar/ListItem'; const style = { diff --git a/apps/meteor/client/components/TextCopy.tsx b/apps/meteor/client/components/TextCopy.tsx index eacc8078d4e9..89d4300687f1 100644 --- a/apps/meteor/client/components/TextCopy.tsx +++ b/apps/meteor/client/components/TextCopy.tsx @@ -1,20 +1,18 @@ import { Box, Icon, Button, Scrollable } from '@rocket.chat/fuselage'; +import { useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback, ComponentProps, ReactElement } from 'react'; -import { useToastMessageDispatch } from '../contexts/ToastMessagesContext'; -import { useTranslation } from '../contexts/TranslationContext'; - -type TextCopyProps = { - text: string; - wrapper?: (text: string) => ReactElement; -} & ComponentProps; - const defaultWrapperRenderer = (text: string): ReactElement => ( {text} ); +type TextCopyProps = { + text: string; + wrapper?: (text: string) => ReactElement; +} & ComponentProps; + const TextCopy = ({ text, wrapper = defaultWrapperRenderer, ...props }: TextCopyProps): ReactElement => { const t = useTranslation(); const dispatchToastMessage = useToastMessageDispatch(); diff --git a/apps/meteor/client/components/TwoFactorModal/TwoFactorEmailModal.tsx b/apps/meteor/client/components/TwoFactorModal/TwoFactorEmailModal.tsx index c29cd9be72e9..fa61a2a3dd12 100644 --- a/apps/meteor/client/components/TwoFactorModal/TwoFactorEmailModal.tsx +++ b/apps/meteor/client/components/TwoFactorModal/TwoFactorEmailModal.tsx @@ -1,10 +1,8 @@ import { Box, TextInput, Icon } from '@rocket.chat/fuselage'; import { useAutoFocus } from '@rocket.chat/fuselage-hooks'; +import { useToastMessageDispatch, useEndpoint, useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement, useState, ChangeEvent } from 'react'; -import { useEndpoint } from '../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../contexts/TranslationContext'; import GenericModal from '../GenericModal'; import { Method, OnConfirm } from './TwoFactorModal'; diff --git a/apps/meteor/client/components/TwoFactorModal/TwoFactorPasswordModal.tsx b/apps/meteor/client/components/TwoFactorModal/TwoFactorPasswordModal.tsx index 2324e9a82616..c9c376b05dbd 100644 --- a/apps/meteor/client/components/TwoFactorModal/TwoFactorPasswordModal.tsx +++ b/apps/meteor/client/components/TwoFactorModal/TwoFactorPasswordModal.tsx @@ -1,8 +1,8 @@ import { Box, PasswordInput, Icon } from '@rocket.chat/fuselage'; import { useAutoFocus } from '@rocket.chat/fuselage-hooks'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement, useState, ChangeEvent, Ref } from 'react'; -import { useTranslation } from '../../contexts/TranslationContext'; import GenericModal from '../GenericModal'; import { Method, OnConfirm } from './TwoFactorModal'; diff --git a/apps/meteor/client/components/TwoFactorModal/TwoFactorTotpModal.tsx b/apps/meteor/client/components/TwoFactorModal/TwoFactorTotpModal.tsx index d69500115fe4..8d514ec6dbc2 100644 --- a/apps/meteor/client/components/TwoFactorModal/TwoFactorTotpModal.tsx +++ b/apps/meteor/client/components/TwoFactorModal/TwoFactorTotpModal.tsx @@ -1,8 +1,8 @@ import { Box, TextInput, Icon } from '@rocket.chat/fuselage'; import { useAutoFocus } from '@rocket.chat/fuselage-hooks'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement, useState, ChangeEvent } from 'react'; -import { useTranslation } from '../../contexts/TranslationContext'; import GenericModal from '../GenericModal'; import { Method, OnConfirm } from './TwoFactorModal'; diff --git a/apps/meteor/client/components/UrlChangeModal.tsx b/apps/meteor/client/components/UrlChangeModal.tsx index 9f16444247dc..194759202533 100644 --- a/apps/meteor/client/components/UrlChangeModal.tsx +++ b/apps/meteor/client/components/UrlChangeModal.tsx @@ -1,7 +1,7 @@ import { Box } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement } from 'react'; -import { useTranslation } from '../contexts/TranslationContext'; import GenericModal from './GenericModal'; type UrlChangeModalProps = { diff --git a/apps/meteor/client/components/UserCard/UserCard.tsx b/apps/meteor/client/components/UserCard/UserCard.tsx index 42a938ac81e4..1e0d32242d77 100644 --- a/apps/meteor/client/components/UserCard/UserCard.tsx +++ b/apps/meteor/client/components/UserCard/UserCard.tsx @@ -1,8 +1,8 @@ import { css } from '@rocket.chat/css-in-js'; import { Box, ActionButton, Skeleton } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { forwardRef, ReactNode, ComponentProps } from 'react'; -import { useTranslation } from '../../contexts/TranslationContext'; import MarkdownText from '../MarkdownText'; import * as Status from '../UserStatus'; import UserAvatar from '../avatar/UserAvatar'; diff --git a/apps/meteor/client/components/UserStatus/UserStatus.tsx b/apps/meteor/client/components/UserStatus/UserStatus.tsx index fde47403baa0..046903e840f1 100644 --- a/apps/meteor/client/components/UserStatus/UserStatus.tsx +++ b/apps/meteor/client/components/UserStatus/UserStatus.tsx @@ -1,8 +1,7 @@ import { StatusBullet } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { memo, ComponentProps, ReactElement } from 'react'; -import { useTranslation } from '../../contexts/TranslationContext'; - export type UserStatusProps = { small?: boolean; statusText?: string; diff --git a/apps/meteor/client/components/UserStatusMenu.js b/apps/meteor/client/components/UserStatusMenu.js deleted file mode 100644 index a95dda44fd58..000000000000 --- a/apps/meteor/client/components/UserStatusMenu.js +++ /dev/null @@ -1,71 +0,0 @@ -import { Button, PositionAnimated, Options, useCursor, Box } from '@rocket.chat/fuselage'; -import React, { useRef, useCallback, useState, useMemo, useEffect } from 'react'; - -import { useSetting } from '../contexts/SettingsContext'; -import { useTranslation } from '../contexts/TranslationContext'; -import { UserStatus } from './UserStatus'; - -const UserStatusMenu = ({ onChange, optionWidth = undefined, initialStatus = 'offline', placement = 'bottom-end', ...props }) => { - const t = useTranslation(); - const [status, setStatus] = useState(initialStatus); - const allowInvisibleStatus = useSetting('Accounts_AllowInvisibleStatusOption'); - - const options = useMemo(() => { - const renderOption = (status, label) => ( - - - - - {label} - - ); - - const statuses = [ - ['online', renderOption('online', t('Online'))], - ['away', renderOption('away', t('Away'))], - ['busy', renderOption('busy', t('Busy'))], - ]; - - if (allowInvisibleStatus) { - statuses.push(['offline', renderOption('offline', t('Invisible'))]); - } - - return statuses; - }, [t, allowInvisibleStatus]); - - const [cursor, handleKeyDown, handleKeyUp, reset, [visible, hide, show]] = useCursor(-1, options, ([selected], [, hide]) => { - setStatus(selected); - reset(); - hide(); - }); - - const ref = useRef(); - const onClick = useCallback(() => { - ref.current.focus() & show(); - ref.current.classList.add('focus-visible'); - }, [show]); - - const handleSelection = useCallback( - ([selected]) => { - setStatus(selected); - reset(); - hide(); - }, - [hide, reset], - ); - - useEffect(() => onChange(status), [status, onChange]); - - return ( - <> - - - - - - ); -}; - -export default UserStatusMenu; diff --git a/apps/meteor/client/components/UserStatusMenu.tsx b/apps/meteor/client/components/UserStatusMenu.tsx new file mode 100644 index 000000000000..c435f26cc8e1 --- /dev/null +++ b/apps/meteor/client/components/UserStatusMenu.tsx @@ -0,0 +1,90 @@ +import { UserStatus as UserStatusType } from '@rocket.chat/core-typings'; +import { Button, PositionAnimated, Options, useCursor, Box } from '@rocket.chat/fuselage'; +import type { Placements } from '@rocket.chat/fuselage-hooks'; +import { useSetting, useTranslation } from '@rocket.chat/ui-contexts'; +import React, { ReactElement, ComponentProps, useRef, useCallback, useState, useMemo, useEffect } from 'react'; + +import { UserStatus } from './UserStatus'; + +type UserStatusMenuProps = { + margin: ComponentProps['margin']; + onChange: (type: UserStatusType) => void; + initialStatus?: UserStatusType; + optionWidth?: ComponentProps['width']; + placement?: Placements; +}; + +const UserStatusMenu = ({ + margin, + onChange, + initialStatus = UserStatusType.OFFLINE, + optionWidth = undefined, + placement = 'bottom-end', +}: UserStatusMenuProps): ReactElement => { + const t = useTranslation(); + const [status, setStatus] = useState(initialStatus); + const allowInvisibleStatus = useSetting('Accounts_AllowInvisibleStatusOption') as boolean; + + const options = useMemo(() => { + const renderOption = (status: UserStatusType, label: string): ReactElement => ( + + + + + {label} + + ); + + const statuses: Array<[value: UserStatusType, label: ReactElement]> = [ + [UserStatusType.ONLINE, renderOption(UserStatusType.ONLINE, t('Online'))], + [UserStatusType.AWAY, renderOption(UserStatusType.AWAY, t('Away'))], + [UserStatusType.BUSY, renderOption(UserStatusType.BUSY, t('Busy'))], + ]; + + if (allowInvisibleStatus) { + statuses.push([UserStatusType.OFFLINE, renderOption(UserStatusType.OFFLINE, t('Invisible'))]); + } + + return statuses; + }, [t, allowInvisibleStatus]); + + const [cursor, handleKeyDown, handleKeyUp, reset, [visible, hide, show]] = useCursor(-1, options, ([selected], [, hide]) => { + setStatus(selected); + reset(); + hide(); + }); + + const ref = useRef(null); + const onClick = useCallback(() => { + if (!ref?.current) { + return; + } + ref.current.focus(); + show(); + ref.current.classList.add('focus-visible'); + }, [show]); + + const handleSelection = useCallback( + ([selected]) => { + setStatus(selected); + reset(); + hide(); + }, + [hide, reset], + ); + + useEffect(() => onChange(status), [status, onChange]); + + return ( + <> + + + + + + ); +}; + +export default UserStatusMenu; diff --git a/apps/meteor/client/components/VerticalBar/VerticalBar.tsx b/apps/meteor/client/components/VerticalBar/VerticalBar.tsx index 6e34172c6cb2..725dd6e99571 100644 --- a/apps/meteor/client/components/VerticalBar/VerticalBar.tsx +++ b/apps/meteor/client/components/VerticalBar/VerticalBar.tsx @@ -1,8 +1,7 @@ import { Box } from '@rocket.chat/fuselage'; +import { useLayoutSizes, useLayoutContextualBarPosition } from '@rocket.chat/ui-contexts'; import React, { FC, ComponentProps, memo } from 'react'; -import { useLayoutContextualBarPosition, useLayoutSizes } from '../../providers/LayoutProvider'; - const VerticalBar: FC> = ({ children, ...props }) => { const sizes = useLayoutSizes(); const position = useLayoutContextualBarPosition(); diff --git a/apps/meteor/client/components/VerticalBar/VerticalBarClose.tsx b/apps/meteor/client/components/VerticalBar/VerticalBarClose.tsx index a5ab5202e42b..e6d908d8150e 100644 --- a/apps/meteor/client/components/VerticalBar/VerticalBarClose.tsx +++ b/apps/meteor/client/components/VerticalBar/VerticalBarClose.tsx @@ -1,6 +1,6 @@ +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { memo, ComponentProps, ReactElement } from 'react'; -import { useTranslation } from '../../contexts/TranslationContext'; import VerticalBarAction from './VerticalBarAction'; type VerticalBarCloseProps = Partial>; diff --git a/apps/meteor/client/components/avatar/RoomAvatar.tsx b/apps/meteor/client/components/avatar/RoomAvatar.tsx index bf450b79b5a7..0c4a1105a721 100644 --- a/apps/meteor/client/components/avatar/RoomAvatar.tsx +++ b/apps/meteor/client/components/avatar/RoomAvatar.tsx @@ -1,6 +1,6 @@ +import { useRoomAvatarPath } from '@rocket.chat/ui-contexts'; import React, { memo, ReactElement } from 'react'; -import { useRoomAvatarPath } from '../../contexts/AvatarUrlContext'; import BaseAvatar from './BaseAvatar'; // TODO: frontend chapter day - Remove inline Styling diff --git a/apps/meteor/client/components/avatar/RoomAvatarEditor.tsx b/apps/meteor/client/components/avatar/RoomAvatarEditor.tsx index c48139bbe6c7..9f51e36b56eb 100644 --- a/apps/meteor/client/components/avatar/RoomAvatarEditor.tsx +++ b/apps/meteor/client/components/avatar/RoomAvatarEditor.tsx @@ -2,10 +2,10 @@ import { IRoom } from '@rocket.chat/core-typings'; import { css } from '@rocket.chat/css-in-js'; import { Box, Button, ButtonGroup, Icon } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { useEffect, ReactElement } from 'react'; import { getAvatarURL } from '../../../app/utils/lib/getAvatarURL'; -import { useTranslation } from '../../contexts/TranslationContext'; import { useFileInput } from '../../hooks/useFileInput'; import RoomAvatar from './RoomAvatar'; diff --git a/apps/meteor/client/components/avatar/UserAvatar.tsx b/apps/meteor/client/components/avatar/UserAvatar.tsx index 90c6404c8756..5b930e29235d 100644 --- a/apps/meteor/client/components/avatar/UserAvatar.tsx +++ b/apps/meteor/client/components/avatar/UserAvatar.tsx @@ -1,6 +1,6 @@ +import { useUserAvatarPath } from '@rocket.chat/ui-contexts'; import React, { FC, memo } from 'react'; -import { useUserAvatarPath } from '../../contexts/AvatarUrlContext'; import BaseAvatar, { BaseAvatarProps } from './BaseAvatar'; type UserAvatarProps = Omit & { diff --git a/apps/meteor/client/components/avatar/UserAvatarEditor/UserAvatarEditor.js b/apps/meteor/client/components/avatar/UserAvatarEditor/UserAvatarEditor.js index 106d36ece21f..0868c9a4a422 100644 --- a/apps/meteor/client/components/avatar/UserAvatarEditor/UserAvatarEditor.js +++ b/apps/meteor/client/components/avatar/UserAvatarEditor/UserAvatarEditor.js @@ -1,9 +1,7 @@ import { Box, Button, Icon, TextInput, Margins, Avatar } from '@rocket.chat/fuselage'; +import { useToastMessageDispatch, useSetting, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useState, useCallback } from 'react'; -import { useSetting } from '../../../contexts/SettingsContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useFileInput } from '../../../hooks/useFileInput'; import UserAvatar from '../UserAvatar'; import UserAvatarSuggestions from './UserAvatarSuggestions'; diff --git a/apps/meteor/client/components/connectionStatus/ConnectionStatusBar.stories.tsx b/apps/meteor/client/components/connectionStatus/ConnectionStatusBar.stories.tsx index 472bfba126bb..fe66879b8b6d 100644 --- a/apps/meteor/client/components/connectionStatus/ConnectionStatusBar.stories.tsx +++ b/apps/meteor/client/components/connectionStatus/ConnectionStatusBar.stories.tsx @@ -1,9 +1,9 @@ +import { ConnectionStatusContext } from '@rocket.chat/ui-contexts'; import { action } from '@storybook/addon-actions'; import { Title, Description, Stories } from '@storybook/addon-docs'; import { ComponentMeta, ComponentStory } from '@storybook/react'; import React, { ContextType, ReactElement } from 'react'; -import { ConnectionStatusContext } from '../../contexts/ConnectionStatusContext'; import ConnectionStatusBar from './ConnectionStatusBar'; export default { diff --git a/apps/meteor/client/components/connectionStatus/ConnectionStatusBar.tsx b/apps/meteor/client/components/connectionStatus/ConnectionStatusBar.tsx index 801c62768624..2dc854547efc 100644 --- a/apps/meteor/client/components/connectionStatus/ConnectionStatusBar.tsx +++ b/apps/meteor/client/components/connectionStatus/ConnectionStatusBar.tsx @@ -1,8 +1,7 @@ import { Icon } from '@rocket.chat/fuselage'; +import { useConnectionStatus, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useEffect, useRef, useState, MouseEventHandler, FC } from 'react'; -import { useConnectionStatus } from '../../contexts/ConnectionStatusContext'; -import { useTranslation } from '../../contexts/TranslationContext'; import './ConnectionStatusBar.styles.css'; // TODO: frontend chapter day - fix unknown translation keys diff --git a/apps/meteor/client/components/voip/composer/NotAvailableOnCall/NotAvailableOnCall.tsx b/apps/meteor/client/components/voip/composer/NotAvailableOnCall/NotAvailableOnCall.tsx index d4e3c6dbb206..c7ec9d722c06 100644 --- a/apps/meteor/client/components/voip/composer/NotAvailableOnCall/NotAvailableOnCall.tsx +++ b/apps/meteor/client/components/voip/composer/NotAvailableOnCall/NotAvailableOnCall.tsx @@ -1,7 +1,7 @@ import { Box } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement } from 'react'; -import { useTranslation } from '../../../../contexts/TranslationContext'; import NotAvailableContent from './NotAvailableContent'; import NotAvailableContentWrapper from './NotAvailableContentWrapper'; diff --git a/apps/meteor/client/components/voip/modal/WrapUpCallModal.tsx b/apps/meteor/client/components/voip/modal/WrapUpCallModal.tsx index 49e585a449ee..104fd5427070 100644 --- a/apps/meteor/client/components/voip/modal/WrapUpCallModal.tsx +++ b/apps/meteor/client/components/voip/modal/WrapUpCallModal.tsx @@ -1,10 +1,9 @@ import { Button, ButtonGroup, Field, Modal, TextAreaInput } from '@rocket.chat/fuselage'; +import { useSetModal, useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement, useEffect } from 'react'; import { useForm, SubmitHandler } from 'react-hook-form'; import { useCallCloseRoom } from '../../../contexts/CallContext'; -import { useSetModal } from '../../../contexts/ModalContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import Tags from '../../Omnichannel/Tags'; type WrapUpCallPayload = { diff --git a/apps/meteor/client/components/voip/room/VoipRoomForeword.tsx b/apps/meteor/client/components/voip/room/VoipRoomForeword.tsx index 352c07b5b106..94046bd40a5a 100644 --- a/apps/meteor/client/components/voip/room/VoipRoomForeword.tsx +++ b/apps/meteor/client/components/voip/room/VoipRoomForeword.tsx @@ -1,9 +1,9 @@ import type { IRoom } from '@rocket.chat/core-typings'; import { Avatar, Box, Tag } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement } from 'react'; import { getUserAvatarURL } from '../../../../app/utils/client'; -import { useTranslation } from '../../../contexts/TranslationContext'; export const VoipRoomForeword = ({ room }: { room: IRoom }): ReactElement => { const t = useTranslation(); diff --git a/apps/meteor/client/components/withDoNotAskAgain.tsx b/apps/meteor/client/components/withDoNotAskAgain.tsx index 916b1bbd6087..c66f31be61ab 100644 --- a/apps/meteor/client/components/withDoNotAskAgain.tsx +++ b/apps/meteor/client/components/withDoNotAskAgain.tsx @@ -1,9 +1,7 @@ import { Box, CheckBox } from '@rocket.chat/fuselage'; +import { useUserPreference, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useState, FC, ReactElement, ComponentType } from 'react'; -import { useMethod } from '../contexts/ServerContext'; -import { useTranslation } from '../contexts/TranslationContext'; -import { useUserPreference } from '../contexts/UserContext'; import { DontAskAgainList } from '../hooks/useDontAskAgain'; type DoNotAskAgainProps = { diff --git a/apps/meteor/client/contexts/AuthorizationContext.ts b/apps/meteor/client/contexts/AuthorizationContext.ts deleted file mode 100644 index 4e5e8c44ce93..000000000000 --- a/apps/meteor/client/contexts/AuthorizationContext.ts +++ /dev/null @@ -1,87 +0,0 @@ -import type { IRole } from '@rocket.chat/core-typings'; -import { Emitter } from '@rocket.chat/emitter'; -import { createContext, useContext, useMemo, useCallback } from 'react'; -import { useSubscription, Subscription, Unsubscribe } from 'use-subscription'; - -type IRoles = { [_id: string]: IRole }; - -export class RoleStore extends Emitter<{ - change: IRoles; -}> { - roles: IRoles = {}; -} - -export type AuthorizationContextValue = { - queryPermission(permission: string | Mongo.ObjectID, scope?: string | Mongo.ObjectID): Subscription; - queryAtLeastOnePermission(permission: (string | Mongo.ObjectID)[], scope?: string | Mongo.ObjectID): Subscription; - queryAllPermissions(permission: (string | Mongo.ObjectID)[], scope?: string | Mongo.ObjectID): Subscription; - queryRole(role: string | Mongo.ObjectID): Subscription; - roleStore: RoleStore; -}; - -export const AuthorizationContext = createContext({ - queryPermission: () => ({ - getCurrentValue: (): boolean => false, - subscribe: (): Unsubscribe => (): void => undefined, - }), - queryAtLeastOnePermission: () => ({ - getCurrentValue: (): boolean => false, - subscribe: (): Unsubscribe => (): void => undefined, - }), - queryAllPermissions: () => ({ - getCurrentValue: (): boolean => false, - subscribe: (): Unsubscribe => (): void => undefined, - }), - queryRole: () => ({ - getCurrentValue: (): boolean => false, - subscribe: (): Unsubscribe => (): void => undefined, - }), - roleStore: new RoleStore(), -}); - -export const usePermission = (permission: string | Mongo.ObjectID, scope?: string | Mongo.ObjectID): boolean => { - const { queryPermission } = useContext(AuthorizationContext); - const subscription = useMemo(() => queryPermission(permission, scope), [queryPermission, permission, scope]); - return useSubscription(subscription); -}; - -export const useAtLeastOnePermission = (permissions: (string | Mongo.ObjectID)[], scope?: string | Mongo.ObjectID): boolean => { - const { queryAtLeastOnePermission } = useContext(AuthorizationContext); - const subscription = useMemo(() => queryAtLeastOnePermission(permissions, scope), [queryAtLeastOnePermission, permissions, scope]); - return useSubscription(subscription); -}; - -export const useAllPermissions = (permissions: (string | Mongo.ObjectID)[], scope?: string | Mongo.ObjectID): boolean => { - const { queryAllPermissions } = useContext(AuthorizationContext); - const subscription = useMemo(() => queryAllPermissions(permissions, scope), [queryAllPermissions, permissions, scope]); - return useSubscription(subscription); -}; - -export const useRolesDescription = (): ((ids: Array) => [string]) => { - const { roleStore } = useContext(AuthorizationContext); - - const subscription = useMemo( - () => ({ - getCurrentValue: (): IRoles => roleStore.roles, - subscribe: (callback: () => void): (() => void) => { - roleStore.on('change', callback); - return (): void => { - roleStore.off('change', callback); - }; - }, - }), - [roleStore], - ); - - const roles = useSubscription(subscription); - - return useCallback((values) => values.map((role) => roles[role]?.description || roles[role]?.name || role), [roles]) as ( - ids: Array, - ) => [string]; -}; - -export const useRole = (role: string | Mongo.ObjectID): boolean => { - const { queryRole } = useContext(AuthorizationContext); - const subscription = useMemo(() => queryRole(role), [queryRole, role]); - return useSubscription(subscription); -}; diff --git a/apps/meteor/client/contexts/AvatarUrlContext.ts b/apps/meteor/client/contexts/AvatarUrlContext.ts deleted file mode 100644 index 985346f774ff..000000000000 --- a/apps/meteor/client/contexts/AvatarUrlContext.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { createContext, useContext } from 'react'; - -const dummy = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQYV2Oora39DwAFaQJ3y3rKeAAAAABJRU5ErkJggg=='; - -type AvatarContextValue = { - getUserPathAvatar: (uid: string, etag?: string) => string; - getRoomPathAvatar: (...args: any) => string; -}; -const AvatarUrlContextValueDefault: AvatarContextValue = { - getUserPathAvatar: () => dummy, - getRoomPathAvatar: () => dummy, -}; - -export const AvatarUrlContext = createContext(AvatarUrlContextValueDefault); - -export const useRoomAvatarPath = (): ((...args: any) => string) => useContext(AvatarUrlContext).getRoomPathAvatar; - -export const useUserAvatarPath = (): ((uid: string, etag?: string) => string) => useContext(AvatarUrlContext).getUserPathAvatar; diff --git a/apps/meteor/client/contexts/ModalContext.ts b/apps/meteor/client/contexts/ModalContext.ts deleted file mode 100644 index 0f36c6ece8ae..000000000000 --- a/apps/meteor/client/contexts/ModalContext.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { createContext, useContext, ReactNode } from 'react'; - -import { modal } from '../../app/ui-utils/client'; - -type ModalContextValue = typeof modal & { - setModal: (modal: ReactNode) => void; -}; - -export const ModalContext = createContext( - Object.assign(modal, { - setModal: () => undefined, - }), -); - -export const useModal = (): ModalContextValue => useContext(ModalContext); - -export const useSetModal = (): ((modal?: ReactNode) => void) => useContext(ModalContext).setModal; diff --git a/apps/meteor/client/contexts/OmnichannelContext.ts b/apps/meteor/client/contexts/OmnichannelContext.ts index fed64e9f1383..f9cf3c53b60b 100644 --- a/apps/meteor/client/contexts/OmnichannelContext.ts +++ b/apps/meteor/client/contexts/OmnichannelContext.ts @@ -1,5 +1,5 @@ -import { OmichannelRoutingConfig, Inquiries } from '@rocket.chat/core-typings'; -import { createContext, useContext } from 'react'; +import type { OmichannelRoutingConfig, Inquiries } from '@rocket.chat/core-typings'; +import { createContext } from 'react'; export type OmnichannelContextValue = { inquiries: Inquiries; @@ -15,10 +15,3 @@ export const OmnichannelContext = createContext({ agentAvailable: false, showOmnichannelQueueLink: false, }); - -export const useOmnichannel = (): OmnichannelContextValue => useContext(OmnichannelContext); -export const useOmnichannelShowQueueLink = (): boolean => useOmnichannel().showOmnichannelQueueLink; -export const useOmnichannelRouteConfig = (): OmichannelRoutingConfig | undefined => useOmnichannel().routeConfig; -export const useOmnichannelAgentAvailable = (): boolean => useOmnichannel().agentAvailable; -export const useQueuedInquiries = (): Inquiries => useOmnichannel().inquiries; -export const useOmnichannelEnabled = (): boolean => useOmnichannel().enabled; diff --git a/apps/meteor/client/contexts/RouterContext.ts b/apps/meteor/client/contexts/RouterContext.ts deleted file mode 100644 index 9909c97d968a..000000000000 --- a/apps/meteor/client/contexts/RouterContext.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { createContext, useContext, useMemo } from 'react'; -import { useSubscription, Subscription } from 'use-subscription'; - -type RouteName = string; - -type RouteParameters = Record; - -type QueryStringParameters = Record; - -type RouteGroupName = string; - -export type RouterContextValue = { - queryRoutePath: ( - name: RouteName, - parameters: RouteParameters | undefined, - queryStringParameters: QueryStringParameters | undefined, - ) => Subscription; - queryRouteUrl: ( - name: RouteName, - parameters: RouteParameters | undefined, - queryStringParameters: QueryStringParameters | undefined, - ) => Subscription; - pushRoute: (name: RouteName, parameters: RouteParameters | undefined, queryStringParameters: QueryStringParameters | undefined) => void; - replaceRoute: ( - name: RouteName, - parameters: RouteParameters | undefined, - queryStringParameters: QueryStringParameters | undefined, - ) => void; - queryRouteParameter: (name: string) => Subscription; - queryQueryStringParameter: (name: string) => Subscription; - queryCurrentRoute: () => Subscription<[RouteName?, RouteParameters?, QueryStringParameters?, RouteGroupName?]>; -}; - -export const RouterContext = createContext({ - queryRoutePath: () => ({ - getCurrentValue: (): undefined => undefined, - subscribe: () => (): void => undefined, - }), - queryRouteUrl: () => ({ - getCurrentValue: (): undefined => undefined, - subscribe: () => (): void => undefined, - }), - pushRoute: () => undefined, - replaceRoute: () => undefined, - queryRouteParameter: () => ({ - getCurrentValue: (): undefined => undefined, - subscribe: () => (): void => undefined, - }), - queryQueryStringParameter: () => ({ - getCurrentValue: (): undefined => undefined, - subscribe: () => (): void => undefined, - }), - queryCurrentRoute: () => ({ - getCurrentValue: (): [undefined, {}, {}, undefined] => [undefined, {}, {}, undefined], - subscribe: () => (): void => undefined, - }), -}); - -type Route = { - getPath: (parameters?: RouteParameters, queryStringParameters?: QueryStringParameters) => string | undefined; - getUrl: (parameters?: RouteParameters, queryStringParameters?: QueryStringParameters) => string | undefined; - push: (parameters?: RouteParameters, queryStringParameters?: QueryStringParameters) => void; - replace: (parameters?: RouteParameters, queryStringParameters?: QueryStringParameters) => void; -}; - -export const useRoute = (name: string): Route => { - const { queryRoutePath, queryRouteUrl, pushRoute, replaceRoute } = useContext(RouterContext); - - return useMemo( - () => ({ - getPath: (parameters, queryStringParameters): string | undefined => - queryRoutePath(name, parameters, queryStringParameters).getCurrentValue(), - getUrl: (parameters, queryStringParameters): ReturnType => - queryRouteUrl(name, parameters, queryStringParameters).getCurrentValue(), - push: (parameters, queryStringParameters): ReturnType => pushRoute(name, parameters, queryStringParameters), - replace: (parameters, queryStringParameters): ReturnType => replaceRoute(name, parameters, queryStringParameters), - }), - [queryRoutePath, queryRouteUrl, name, pushRoute, replaceRoute], - ); -}; - -export const useRoutePath = ( - name: string, - parameters?: RouteParameters, - queryStringParameters?: QueryStringParameters, -): string | undefined => { - const { queryRoutePath } = useContext(RouterContext); - - return useSubscription( - useMemo(() => queryRoutePath(name, parameters, queryStringParameters), [queryRoutePath, name, parameters, queryStringParameters]), - ); -}; - -export const useRouteUrl = ( - name: string, - parameters?: RouteParameters, - queryStringParameters?: QueryStringParameters, -): string | undefined => { - const { queryRouteUrl } = useContext(RouterContext); - - return useSubscription( - useMemo(() => queryRouteUrl(name, parameters, queryStringParameters), [queryRouteUrl, name, parameters, queryStringParameters]), - ); -}; - -export const useRouteParameter = (name: string): string | undefined => { - const { queryRouteParameter } = useContext(RouterContext); - - return useSubscription(useMemo(() => queryRouteParameter(name), [queryRouteParameter, name])); -}; - -export const useQueryStringParameter = (name: string): string | undefined => { - const { queryQueryStringParameter } = useContext(RouterContext); - - return useSubscription(useMemo(() => queryQueryStringParameter(name), [queryQueryStringParameter, name])); -}; - -export const useCurrentRoute = (): [RouteName?, RouteParameters?, QueryStringParameters?, RouteGroupName?] => { - const { queryCurrentRoute } = useContext(RouterContext); - - return useSubscription(useMemo(() => queryCurrentRoute(), [queryCurrentRoute])); -}; diff --git a/apps/meteor/client/contexts/ServerContext/ServerContext.ts b/apps/meteor/client/contexts/ServerContext/ServerContext.ts deleted file mode 100644 index 395b5b344f3a..000000000000 --- a/apps/meteor/client/contexts/ServerContext/ServerContext.ts +++ /dev/null @@ -1,99 +0,0 @@ -import type { IServerInfo, Serialized } from '@rocket.chat/core-typings'; -import type { Method, PathFor, OperationParams, MatchPathPattern, OperationResult, PathPattern } from '@rocket.chat/rest-typings'; -import { createContext, useCallback, useContext, useMemo } from 'react'; - -import { ServerMethodFunction, ServerMethodName, ServerMethodParameters, ServerMethodReturn, ServerMethods } from './methods'; - -export type UploadResult = { - success: boolean; - status: string; - [key: string]: unknown; -}; -type ServerContextValue = { - info?: IServerInfo; - absoluteUrl: (path: string) => string; - callMethod?: ( - methodName: MethodName, - ...args: ServerMethodParameters - ) => Promise>; - callEndpoint: >( - method: TMethod, - path: TPath, - params: Serialized>>, - ) => Promise>>>; - uploadToEndpoint: ( - endpoint: string, - params: any, - formData: any, - ) => - | Promise - | { - promise: Promise; - }; - getStream: (streamName: string, options?: {}) => (eventName: string, callback: (data: T) => void) => () => void; -}; - -export const ServerContext = createContext({ - info: undefined, - absoluteUrl: (path) => path, - callEndpoint: () => { - throw new Error('not implemented'); - }, - uploadToEndpoint: async () => { - throw new Error('not implemented'); - }, - getStream: () => () => (): void => undefined, -}); - -export const useServerInformation = (): IServerInfo => { - const { info } = useContext(ServerContext); - if (!info) { - throw new Error('useServerInformation: no info available'); - } - return info; -}; - -export const useAbsoluteUrl = (): ((path: string) => string) => useContext(ServerContext).absoluteUrl; - -export const useMethod = (methodName: MethodName): ServerMethodFunction => { - const { callMethod } = useContext(ServerContext); - - return useCallback( - (...args: ServerMethodParameters) => { - if (!callMethod) { - throw new Error(`cannot use useMethod(${methodName}) hook without a wrapping ServerContext`); - } - - return callMethod(methodName, ...args); - }, - [callMethod, methodName], - ); -}; - -type EndpointFunction = ( - params: void extends OperationParams ? void : Serialized>, -) => Promise>>; - -export const useEndpoint = >( - method: TMethod, - path: TPath, -): EndpointFunction> => { - const { callEndpoint } = useContext(ServerContext); - - return useCallback( - (params: Serialized>>) => callEndpoint(method, path, params), - [callEndpoint, path, method], - ); -}; - -export const useUpload = ( - endpoint: string, -): ((params: any, formData: any) => Promise | { promise: Promise }) => { - const { uploadToEndpoint } = useContext(ServerContext); - return useCallback((params, formData: any) => uploadToEndpoint(endpoint, params, formData), [endpoint, uploadToEndpoint]); -}; - -export const useStream = (streamName: string, options?: {}): ((eventName: string, callback: (data: T) => void) => () => void) => { - const { getStream } = useContext(ServerContext); - return useMemo(() => getStream(streamName, options), [getStream, streamName, options]); -}; diff --git a/apps/meteor/client/contexts/SessionContext.ts b/apps/meteor/client/contexts/SessionContext.ts deleted file mode 100644 index 4d12f2aa87ef..000000000000 --- a/apps/meteor/client/contexts/SessionContext.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { createContext, useCallback, useContext, useMemo } from 'react'; -import { useSubscription, Subscription, Unsubscribe } from 'use-subscription'; - -type SessionContextValue = { - query: (name: string) => Subscription; - dispatch: (name: string, value: unknown) => void; -}; - -export const SessionContext = createContext({ - query: () => ({ - getCurrentValue: (): undefined => undefined, - subscribe: (): Unsubscribe => (): void => undefined, - }), - dispatch: (): void => undefined, -}); - -export const useSession = (name: string): unknown => { - const { query } = useContext(SessionContext); - const subscription = useMemo(() => query(name), [query, name]); - return useSubscription(subscription); -}; - -export const useSessionDispatch = (name: string): ((value: unknown) => void) => { - const { dispatch } = useContext(SessionContext); - return useCallback((value) => dispatch(name, value), [dispatch, name]); -}; diff --git a/apps/meteor/client/contexts/SettingsContext.ts b/apps/meteor/client/contexts/SettingsContext.ts deleted file mode 100644 index 17c76b06d849..000000000000 --- a/apps/meteor/client/contexts/SettingsContext.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { SettingId, ISetting, GroupId, SectionName, TabId } from '@rocket.chat/core-typings'; -import { createContext, useCallback, useContext, useMemo } from 'react'; -import { useSubscription, Subscription, Unsubscribe } from 'use-subscription'; - -export type SettingsContextQuery = { - readonly _id?: SettingId[]; - readonly group?: GroupId; - readonly section?: SectionName; - readonly tab?: TabId; -}; - -export type SettingsContextValue = { - readonly hasPrivateAccess: boolean; - readonly isLoading: boolean; - readonly querySetting: (_id: SettingId) => Subscription; - readonly querySettings: (query: SettingsContextQuery) => Subscription; - readonly dispatch: (changes: Partial[]) => Promise; -}; - -export const SettingsContext = createContext({ - hasPrivateAccess: false, - isLoading: false, - querySetting: () => ({ - getCurrentValue: (): undefined => undefined, - subscribe: (): Unsubscribe => (): void => undefined, - }), - querySettings: () => ({ - getCurrentValue: (): ISetting[] => [], - subscribe: (): Unsubscribe => (): void => undefined, - }), - dispatch: async () => undefined, -}); - -export const useIsPrivilegedSettingsContext = (): boolean => useContext(SettingsContext).hasPrivateAccess; - -export const useIsSettingsContextLoading = (): boolean => useContext(SettingsContext).isLoading; - -export const useSettingStructure = (_id: SettingId): ISetting | undefined => { - const { querySetting } = useContext(SettingsContext); - const subscription = useMemo(() => querySetting(_id), [querySetting, _id]); - return useSubscription(subscription); -}; - -export const useSetting = (_id: SettingId): unknown | undefined => useSettingStructure(_id)?.value; - -export const useSettings = (query?: SettingsContextQuery): ISetting[] => { - const { querySettings } = useContext(SettingsContext); - const subscription = useMemo(() => querySettings(query ?? {}), [querySettings, query]); - return useSubscription(subscription); -}; - -export const useSettingsDispatch = (): ((changes: Partial[]) => Promise) => useContext(SettingsContext).dispatch; - -export const useSettingSetValue = (_id: SettingId): ((value: T) => Promise) => { - const dispatch = useSettingsDispatch(); - return useCallback((value: T) => dispatch([{ _id, value }]), [dispatch, _id]); -}; diff --git a/apps/meteor/client/contexts/SidebarContext.ts b/apps/meteor/client/contexts/SidebarContext.ts deleted file mode 100644 index 30182fbb7f74..000000000000 --- a/apps/meteor/client/contexts/SidebarContext.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { createContext, useContext } from 'react'; - -type SidebarContextValue = [boolean, (open: boolean | ((isOpen: boolean) => boolean)) => void]; - -export const SidebarContext = createContext([false, (): void => undefined]); - -export const useSidebar = (): SidebarContextValue => useContext(SidebarContext); diff --git a/apps/meteor/client/contexts/TooltipContext.ts b/apps/meteor/client/contexts/TooltipContext.ts deleted file mode 100644 index 38c46f46fe4f..000000000000 --- a/apps/meteor/client/contexts/TooltipContext.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { createContext, ReactElement, useContext } from 'react'; - -type TooltipPayload = ReactElement; - -type TooltipContextValue = { - open: (payload: TooltipPayload, anchor: HTMLElement) => void; - close: () => void; -}; - -export const TooltipContext = createContext({ - open: () => undefined, - close: () => undefined, -}); - -export const useTooltipOpen = (): TooltipContextValue['open'] => useContext(TooltipContext).open; -export const useTooltipClose = (): TooltipContextValue['close'] => useContext(TooltipContext).close; diff --git a/apps/meteor/client/contexts/UserContext.ts b/apps/meteor/client/contexts/UserContext.ts deleted file mode 100644 index f42934aae608..000000000000 --- a/apps/meteor/client/contexts/UserContext.ts +++ /dev/null @@ -1,116 +0,0 @@ -import type { IRoom, ISubscription, IUser } from '@rocket.chat/core-typings'; -import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; -import { FilterQuery } from 'mongodb'; -import { createContext, useContext, useMemo } from 'react'; -import { useSubscription, Subscription, Unsubscribe } from 'use-subscription'; - -import { useRoute } from './RouterContext'; - -type SubscriptionQuery = - | { - rid: string | Mongo.ObjectID; - } - | { - name: string; - } - | { - open: boolean; - } - | object; - -type Fields = { - [key: string]: boolean; -}; - -type Sort = { - [key: string]: -1 | 1 | number; -}; - -type FindOptions = { - fields?: Fields; - sort?: Sort; -}; - -type UserContextValue = { - userId: string | null; - user: IUser | null; - loginWithPassword: (user: string | object, password: string) => Promise; - logout: () => Promise; - queryPreference: (key: string | Mongo.ObjectID, defaultValue?: T) => Subscription; - querySubscription: (query: FilterQuery, fields?: Fields, sort?: Sort) => Subscription; - queryRoom: (query: FilterQuery, fields?: Fields, sort?: Sort) => Subscription; - querySubscriptions: (query: SubscriptionQuery, options?: FindOptions) => Subscription | []>; -}; - -export const UserContext = createContext({ - userId: null, - user: null, - loginWithPassword: async () => undefined, - logout: () => Promise.resolve(), - queryPreference: () => ({ - getCurrentValue: (): undefined => undefined, - subscribe: (): Unsubscribe => (): void => undefined, - }), - querySubscription: () => ({ - getCurrentValue: (): undefined => undefined, - subscribe: (): Unsubscribe => (): void => undefined, - }), - queryRoom: () => ({ - getCurrentValue: (): undefined => undefined, - subscribe: (): Unsubscribe => (): void => undefined, - }), - querySubscriptions: () => ({ - getCurrentValue: (): [] => [], - subscribe: (): Unsubscribe => (): void => undefined, - }), -}); - -export const useUserId = (): string | null => useContext(UserContext).userId; - -// TODO: Use IUser instead -export const useUser = (): IUser | null => useContext(UserContext).user; - -export const useLoginWithPassword = (): ((user: string | object, password: string) => Promise) => - useContext(UserContext).loginWithPassword; - -export const useLogout = (): (() => void) => { - const router = useRoute('home'); - const { logout } = useContext(UserContext); - - const handleLogout = useMutableCallback(() => { - logout(); - router.push({}); - }); - - return handleLogout; -}; - -export const useUserPreference = (key: string, defaultValue?: T): T | undefined => { - const { queryPreference } = useContext(UserContext); - const subscription = useMemo(() => queryPreference(key, defaultValue), [queryPreference, key, defaultValue]); - return useSubscription(subscription); -}; - -export const useUserSubscription = (rid: string, fields?: Fields): ISubscription | undefined => { - const { querySubscription } = useContext(UserContext); - const subscription = useMemo(() => querySubscription({ rid }, fields), [querySubscription, rid, fields]); - return useSubscription(subscription); -}; - -export const useUserRoom = (rid: string, fields?: Fields): IRoom | undefined => { - const { queryRoom } = useContext(UserContext); - const subscription = useMemo(() => queryRoom({ _id: rid }, fields), [queryRoom, rid, fields]); - return useSubscription(subscription); -}; - -export const useUserSubscriptions = (query: SubscriptionQuery, options?: FindOptions): Array | [] => { - const { querySubscriptions } = useContext(UserContext); - const subscription = useMemo(() => querySubscriptions(query, options), [querySubscriptions, query, options]); - return useSubscription(subscription); -}; - -export const useUserSubscriptionByName = (name: string, fields: Fields, sort?: Sort): ISubscription | undefined => { - const { querySubscription } = useContext(UserContext); - const subscription = useMemo(() => querySubscription({ name }, fields, sort), [querySubscription, name, fields, sort]); - return useSubscription(subscription); -}; diff --git a/apps/meteor/client/hooks/lists/useStreamUpdatesForMessageList.ts b/apps/meteor/client/hooks/lists/useStreamUpdatesForMessageList.ts index dcb4eb79bf81..b134bb090e30 100644 --- a/apps/meteor/client/hooks/lists/useStreamUpdatesForMessageList.ts +++ b/apps/meteor/client/hooks/lists/useStreamUpdatesForMessageList.ts @@ -1,7 +1,7 @@ import type { IMessage, IRoom, IUser } from '@rocket.chat/core-typings'; +import { useStream } from '@rocket.chat/ui-contexts'; import { useEffect } from 'react'; -import { useStream } from '../../contexts/ServerContext'; import { MessageList } from '../../lib/lists/MessageList'; import { createFilterFromQuery, FieldExpression, Query } from '../../lib/minimongo'; diff --git a/apps/meteor/client/hooks/omnichannel/useOmnichannel.ts b/apps/meteor/client/hooks/omnichannel/useOmnichannel.ts new file mode 100644 index 000000000000..140df083dabe --- /dev/null +++ b/apps/meteor/client/hooks/omnichannel/useOmnichannel.ts @@ -0,0 +1,5 @@ +import { useContext } from 'react'; + +import { OmnichannelContext, OmnichannelContextValue } from '../../contexts/OmnichannelContext'; + +export const useOmnichannel = (): OmnichannelContextValue => useContext(OmnichannelContext); diff --git a/apps/meteor/client/hooks/omnichannel/useOmnichannelAgentAvailable.ts b/apps/meteor/client/hooks/omnichannel/useOmnichannelAgentAvailable.ts new file mode 100644 index 000000000000..f00ee0116f07 --- /dev/null +++ b/apps/meteor/client/hooks/omnichannel/useOmnichannelAgentAvailable.ts @@ -0,0 +1,3 @@ +import { useOmnichannel } from './useOmnichannel'; + +export const useOmnichannelAgentAvailable = (): boolean => useOmnichannel().agentAvailable; diff --git a/apps/meteor/client/hooks/omnichannel/useOmnichannelEnabled.ts b/apps/meteor/client/hooks/omnichannel/useOmnichannelEnabled.ts new file mode 100644 index 000000000000..47b461ee3e9c --- /dev/null +++ b/apps/meteor/client/hooks/omnichannel/useOmnichannelEnabled.ts @@ -0,0 +1,3 @@ +import { useOmnichannel } from './useOmnichannel'; + +export const useOmnichannelEnabled = (): boolean => useOmnichannel().enabled; diff --git a/apps/meteor/client/hooks/omnichannel/useOmnichannelRouteConfig.ts b/apps/meteor/client/hooks/omnichannel/useOmnichannelRouteConfig.ts new file mode 100644 index 000000000000..ec1234d0a5d5 --- /dev/null +++ b/apps/meteor/client/hooks/omnichannel/useOmnichannelRouteConfig.ts @@ -0,0 +1,5 @@ +import type { OmichannelRoutingConfig } from '@rocket.chat/core-typings'; + +import { useOmnichannel } from './useOmnichannel'; + +export const useOmnichannelRouteConfig = (): OmichannelRoutingConfig | undefined => useOmnichannel().routeConfig; diff --git a/apps/meteor/client/hooks/omnichannel/useOmnichannelShowQueueLink.ts b/apps/meteor/client/hooks/omnichannel/useOmnichannelShowQueueLink.ts new file mode 100644 index 000000000000..da32e9b11449 --- /dev/null +++ b/apps/meteor/client/hooks/omnichannel/useOmnichannelShowQueueLink.ts @@ -0,0 +1,3 @@ +import { useOmnichannel } from './useOmnichannel'; + +export const useOmnichannelShowQueueLink = (): boolean => useOmnichannel().showOmnichannelQueueLink; diff --git a/apps/meteor/client/hooks/omnichannel/useQueuedInquiries.ts b/apps/meteor/client/hooks/omnichannel/useQueuedInquiries.ts new file mode 100644 index 000000000000..ed9f911a2ba5 --- /dev/null +++ b/apps/meteor/client/hooks/omnichannel/useQueuedInquiries.ts @@ -0,0 +1,5 @@ +import type { Inquiries } from '@rocket.chat/core-typings'; + +import { useOmnichannel } from './useOmnichannel'; + +export const useQueuedInquiries = (): Inquiries => useOmnichannel().inquiries; diff --git a/apps/meteor/client/hooks/useClipboardWithToast.ts b/apps/meteor/client/hooks/useClipboardWithToast.ts index e862ec0b4f7c..51d5f4b66869 100644 --- a/apps/meteor/client/hooks/useClipboardWithToast.ts +++ b/apps/meteor/client/hooks/useClipboardWithToast.ts @@ -1,7 +1,5 @@ import { useClipboard, UseClipboardReturn, useMutableCallback } from '@rocket.chat/fuselage-hooks'; - -import { useToastMessageDispatch } from '../contexts/ToastMessagesContext'; -import { useTranslation } from '../contexts/TranslationContext'; +import { useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts'; export default function useClipboardWithToast(text: string): UseClipboardReturn { const t = useTranslation(); diff --git a/apps/meteor/client/hooks/useDontAskAgain.ts b/apps/meteor/client/hooks/useDontAskAgain.ts index d073af6cc340..b0c926cd7dfd 100644 --- a/apps/meteor/client/hooks/useDontAskAgain.ts +++ b/apps/meteor/client/hooks/useDontAskAgain.ts @@ -1,4 +1,4 @@ -import { useUserPreference } from '../contexts/UserContext'; +import { useUserPreference } from '@rocket.chat/ui-contexts'; export type DontAskAgainList = Array<{ action: string; label: string }>; diff --git a/apps/meteor/client/hooks/useEmbeddedLayout.ts b/apps/meteor/client/hooks/useEmbeddedLayout.ts index 5563535d3ded..d326e221eb94 100644 --- a/apps/meteor/client/hooks/useEmbeddedLayout.ts +++ b/apps/meteor/client/hooks/useEmbeddedLayout.ts @@ -1,3 +1,3 @@ -import { useQueryStringParameter } from '../contexts/RouterContext'; +import { useQueryStringParameter } from '@rocket.chat/ui-contexts'; export const useEmbeddedLayout = (): boolean => useQueryStringParameter('layout') === 'embedded'; diff --git a/apps/meteor/client/hooks/useEndpointAction.ts b/apps/meteor/client/hooks/useEndpointAction.ts index 4ccb9b35815e..76c86d648dfe 100644 --- a/apps/meteor/client/hooks/useEndpointAction.ts +++ b/apps/meteor/client/hooks/useEndpointAction.ts @@ -1,10 +1,8 @@ import { Serialized } from '@rocket.chat/core-typings'; import type { MatchPathPattern, Method, OperationParams, OperationResult, PathFor } from '@rocket.chat/rest-typings'; +import { useToastMessageDispatch, useEndpoint } from '@rocket.chat/ui-contexts'; import { useCallback } from 'react'; -import { useEndpoint } from '../contexts/ServerContext'; -import { useToastMessageDispatch } from '../contexts/ToastMessagesContext'; - export const useEndpointAction = >( method: TMethod, path: TPath, diff --git a/apps/meteor/client/hooks/useEndpointActionExperimental.ts b/apps/meteor/client/hooks/useEndpointActionExperimental.ts index 7b1c2014b016..45ed08906f71 100644 --- a/apps/meteor/client/hooks/useEndpointActionExperimental.ts +++ b/apps/meteor/client/hooks/useEndpointActionExperimental.ts @@ -1,10 +1,8 @@ import { Serialized } from '@rocket.chat/core-typings'; import type { MatchPathPattern, Method, OperationParams, OperationResult, PathFor } from '@rocket.chat/rest-typings'; +import { useToastMessageDispatch, useEndpoint } from '@rocket.chat/ui-contexts'; import { useCallback } from 'react'; -import { useEndpoint } from '../contexts/ServerContext'; -import { useToastMessageDispatch } from '../contexts/ToastMessagesContext'; - export const useEndpointActionExperimental = >( method: TMethod, path: TPath, diff --git a/apps/meteor/client/hooks/useEndpointData.ts b/apps/meteor/client/hooks/useEndpointData.ts index e9e9d70aa29f..4c7a289da029 100644 --- a/apps/meteor/client/hooks/useEndpointData.ts +++ b/apps/meteor/client/hooks/useEndpointData.ts @@ -1,9 +1,8 @@ import { Serialized } from '@rocket.chat/core-typings'; import type { MatchPathPattern, OperationParams, OperationResult, PathFor } from '@rocket.chat/rest-typings'; +import { useToastMessageDispatch, useEndpoint } from '@rocket.chat/ui-contexts'; import { useCallback, useEffect } from 'react'; -import { useEndpoint } from '../contexts/ServerContext'; -import { useToastMessageDispatch } from '../contexts/ToastMessagesContext'; import { AsyncState, useAsyncState } from './useAsyncState'; export const useEndpointData = >( diff --git a/apps/meteor/client/hooks/useEndpointUpload.ts b/apps/meteor/client/hooks/useEndpointUpload.ts index 713397b04373..8a699171aa92 100644 --- a/apps/meteor/client/hooks/useEndpointUpload.ts +++ b/apps/meteor/client/hooks/useEndpointUpload.ts @@ -1,8 +1,6 @@ +import { useToastMessageDispatch, UploadResult, useUpload } from '@rocket.chat/ui-contexts'; import { useCallback } from 'react'; -import { UploadResult, useUpload } from '../contexts/ServerContext'; -import { useToastMessageDispatch } from '../contexts/ToastMessagesContext'; - export const useEndpointUpload = ( endpoint: string, params = {}, diff --git a/apps/meteor/client/hooks/useFormatDate.ts b/apps/meteor/client/hooks/useFormatDate.ts index a58b3a30bfeb..f3390f5ac879 100644 --- a/apps/meteor/client/hooks/useFormatDate.ts +++ b/apps/meteor/client/hooks/useFormatDate.ts @@ -1,8 +1,7 @@ +import { useSetting } from '@rocket.chat/ui-contexts'; import moment from 'moment'; import { useCallback } from 'react'; -import { useSetting } from '../contexts/SettingsContext'; - export const useFormatDate = (): ((time: string | Date | number) => string) => { const format = useSetting('Message_DateFormat'); return useCallback((time) => moment(time).format(String(format)), [format]); diff --git a/apps/meteor/client/hooks/useFormatDateAndTime.ts b/apps/meteor/client/hooks/useFormatDateAndTime.ts index 0bda2b2350e4..8028a9ac3046 100644 --- a/apps/meteor/client/hooks/useFormatDateAndTime.ts +++ b/apps/meteor/client/hooks/useFormatDateAndTime.ts @@ -1,9 +1,7 @@ +import { useUserPreference, useSetting } from '@rocket.chat/ui-contexts'; import moment, { MomentInput } from 'moment'; import { useCallback } from 'react'; -import { useSetting } from '../contexts/SettingsContext'; -import { useUserPreference } from '../contexts/UserContext'; - type UseFormatDateAndTimeParams = { withSeconds?: boolean; }; diff --git a/apps/meteor/client/hooks/useFormatDuration.ts b/apps/meteor/client/hooks/useFormatDuration.ts index 76d870e4cbe4..61215074dfbd 100644 --- a/apps/meteor/client/hooks/useFormatDuration.ts +++ b/apps/meteor/client/hooks/useFormatDuration.ts @@ -1,7 +1,6 @@ +import { useTranslation } from '@rocket.chat/ui-contexts'; import { useCallback } from 'react'; -import { useTranslation } from '../contexts/TranslationContext'; - export const useFormatDuration = (): ((duration: number) => string) => { const t = useTranslation(); diff --git a/apps/meteor/client/hooks/useFormatTime.ts b/apps/meteor/client/hooks/useFormatTime.ts index 092773ec2eb6..b1f7e2288ab8 100644 --- a/apps/meteor/client/hooks/useFormatTime.ts +++ b/apps/meteor/client/hooks/useFormatTime.ts @@ -1,9 +1,7 @@ +import { useUserPreference, useSetting } from '@rocket.chat/ui-contexts'; import moment from 'moment'; import { useCallback } from 'react'; -import { useSetting } from '../contexts/SettingsContext'; -import { useUserPreference } from '../contexts/UserContext'; - const dayFormat = ['h:mm A', 'H:mm'] as const; export const useFormatTime = (): ((input: moment.MomentInput) => string) => { diff --git a/apps/meteor/client/hooks/useLocalePercentage.ts b/apps/meteor/client/hooks/useLocalePercentage.ts index 23323a077911..902ae7011e7f 100644 --- a/apps/meteor/client/hooks/useLocalePercentage.ts +++ b/apps/meteor/client/hooks/useLocalePercentage.ts @@ -1,4 +1,5 @@ -import { useLanguage } from '../contexts/TranslationContext'; +import { useLanguage } from '@rocket.chat/ui-contexts'; + import { getLocalePercentage } from '../lib/getLocalePercentage'; export const useLocalePercentage = (total: number, fraction: number, decimalCount: number | undefined): string => { diff --git a/apps/meteor/client/hooks/useMethodData.ts b/apps/meteor/client/hooks/useMethodData.ts index f875b9e15485..3c7388cc17a6 100644 --- a/apps/meteor/client/hooks/useMethodData.ts +++ b/apps/meteor/client/hooks/useMethodData.ts @@ -1,8 +1,7 @@ import type { Awaited } from '@rocket.chat/core-typings'; +import { useToastMessageDispatch, ServerMethodFunction, ServerMethodParameters, ServerMethods, useMethod } from '@rocket.chat/ui-contexts'; import { useCallback, useEffect } from 'react'; -import { ServerMethodFunction, ServerMethodParameters, ServerMethods, useMethod } from '../contexts/ServerContext'; -import { useToastMessageDispatch } from '../contexts/ToastMessagesContext'; import { AsyncState, useAsyncState } from './useAsyncState'; export const useMethodData = >>>( diff --git a/apps/meteor/client/hooks/usePolledMethodData.ts b/apps/meteor/client/hooks/usePolledMethodData.ts index da5197f6b156..dce09ebba935 100644 --- a/apps/meteor/client/hooks/usePolledMethodData.ts +++ b/apps/meteor/client/hooks/usePolledMethodData.ts @@ -1,7 +1,7 @@ import { Awaited } from '@rocket.chat/core-typings'; +import { ServerMethodFunction, ServerMethodParameters, ServerMethods } from '@rocket.chat/ui-contexts'; import { useEffect } from 'react'; -import { ServerMethodFunction, ServerMethodParameters, ServerMethods } from '../contexts/ServerContext'; import { AsyncState } from './useAsyncState'; import { useMethodData } from './useMethodData'; diff --git a/apps/meteor/client/hooks/useUpdateAvatar.ts b/apps/meteor/client/hooks/useUpdateAvatar.ts index d4968158e75f..ae9eb2336d3e 100644 --- a/apps/meteor/client/hooks/useUpdateAvatar.ts +++ b/apps/meteor/client/hooks/useUpdateAvatar.ts @@ -1,9 +1,7 @@ import { IUser } from '@rocket.chat/core-typings'; +import { useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import { useMemo, useCallback } from 'react'; -import { useMethod } from '../contexts/ServerContext'; -import { useToastMessageDispatch } from '../contexts/ToastMessagesContext'; -import { useTranslation } from '../contexts/TranslationContext'; import { useEndpointAction } from './useEndpointAction'; import { useEndpointUpload } from './useEndpointUpload'; diff --git a/apps/meteor/client/hooks/useUserDisplayName.ts b/apps/meteor/client/hooks/useUserDisplayName.ts index 13fee5952f4e..5d04600cdecf 100644 --- a/apps/meteor/client/hooks/useUserDisplayName.ts +++ b/apps/meteor/client/hooks/useUserDisplayName.ts @@ -1,6 +1,6 @@ import type { IUser } from '@rocket.chat/core-typings'; +import { useSetting } from '@rocket.chat/ui-contexts'; -import { useSetting } from '../contexts/SettingsContext'; import { getUserDisplayName } from '../lib/getUserDisplayName'; export const useUserDisplayName = ({ name, username }: Pick): string | undefined => { diff --git a/apps/meteor/client/importPackages.ts b/apps/meteor/client/importPackages.ts index fc5877e0faf4..4ee4fc8b4688 100644 --- a/apps/meteor/client/importPackages.ts +++ b/apps/meteor/client/importPackages.ts @@ -24,7 +24,6 @@ import '../app/importer-csv/client'; import '../app/importer-hipchat-enterprise/client'; import '../app/importer-slack/client'; import '../app/importer-slack-users/client'; -import '../app/integrations/client/startup'; import '../app/lib/client'; import '../app/livestream/client'; import '../app/logger/client'; @@ -77,7 +76,6 @@ import '../app/chatpal-search/client'; import '../app/lazy-load/client'; import '../app/discussion/client'; import '../app/threads/client'; -import '../app/mail-messages/client'; import '../app/user-status/client'; import '../app/utils/client'; import '../app/settings/client'; diff --git a/apps/meteor/client/lib/RoomManager.ts b/apps/meteor/client/lib/RoomManager.ts index 44303d3dd7bf..31a0d5f0b78a 100644 --- a/apps/meteor/client/lib/RoomManager.ts +++ b/apps/meteor/client/lib/RoomManager.ts @@ -1,10 +1,10 @@ import type { IRoom } from '@rocket.chat/core-typings'; import { Emitter } from '@rocket.chat/emitter'; +import { useUserId, useUserRoom, useUserSubscription } from '@rocket.chat/ui-contexts'; import { useEffect, useMemo } from 'react'; import { useSubscription, Subscription, Unsubscribe } from 'use-subscription'; import { RoomHistoryManager } from '../../app/ui-utils/client/lib/RoomHistoryManager'; -import { useUserId, useUserRoom, useUserSubscription } from '../contexts/UserContext'; import { useAsyncState } from '../hooks/useAsyncState'; import { AsyncState } from './asyncState'; import { getConfig } from './utils/getConfig'; diff --git a/apps/meteor/client/lib/utils/call.ts b/apps/meteor/client/lib/utils/call.ts index 093928d18c72..1cf72a66f3e6 100644 --- a/apps/meteor/client/lib/utils/call.ts +++ b/apps/meteor/client/lib/utils/call.ts @@ -1,7 +1,6 @@ +import { ServerMethodName, ServerMethodParameters, ServerMethodReturn } from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; -import { ServerMethodName, ServerMethodParameters, ServerMethodReturn } from '../../contexts/ServerContext'; - export const call = (method: M, ...params: ServerMethodParameters): Promise> => new Promise((resolve, reject) => { Meteor.call(method, ...params, (error: Error, result: ServerMethodReturn) => { diff --git a/apps/meteor/client/lib/utils/callWithErrorHandling.ts b/apps/meteor/client/lib/utils/callWithErrorHandling.ts index 141c6fe10735..2436a2fac6ac 100644 --- a/apps/meteor/client/lib/utils/callWithErrorHandling.ts +++ b/apps/meteor/client/lib/utils/callWithErrorHandling.ts @@ -1,4 +1,5 @@ -import { ServerMethodName, ServerMethodParameters, ServerMethodReturn } from '../../contexts/ServerContext'; +import { ServerMethodName, ServerMethodParameters, ServerMethodReturn } from '@rocket.chat/ui-contexts'; + import { call } from './call'; import { handleError } from './handleError'; diff --git a/apps/meteor/client/main.ts b/apps/meteor/client/main.ts index fa275fb1610e..628050600a12 100644 --- a/apps/meteor/client/main.ts +++ b/apps/meteor/client/main.ts @@ -1,4 +1,6 @@ import '../ee/definition/rest'; +import '../ee/definition/methods'; +import '../definition/methods'; import '../ee/client/ecdh'; import './polyfills'; diff --git a/apps/meteor/client/providers/AuthorizationProvider.tsx b/apps/meteor/client/providers/AuthorizationProvider.tsx index 4cbc80f53d58..c5e360169b62 100644 --- a/apps/meteor/client/providers/AuthorizationProvider.tsx +++ b/apps/meteor/client/providers/AuthorizationProvider.tsx @@ -1,12 +1,20 @@ +import { IRole } from '@rocket.chat/core-typings'; +import { Emitter } from '@rocket.chat/emitter'; +import { AuthorizationContext } from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; import React, { FC, useCallback, useEffect } from 'react'; import { hasPermission, hasAtLeastOnePermission, hasAllPermission, hasRole } from '../../app/authorization/client'; import { Roles } from '../../app/models/client/models/Roles'; -import { AuthorizationContext, RoleStore } from '../contexts/AuthorizationContext'; import { useReactiveValue } from '../hooks/useReactiveValue'; import { createReactiveSubscriptionFactory } from './createReactiveSubscriptionFactory'; +class RoleStore extends Emitter<{ + change: { [_id: string]: IRole }; +}> { + roles: { [_id: string]: IRole } = {}; +} + const contextValue = { queryPermission: createReactiveSubscriptionFactory((permission, scope) => hasPermission(permission, scope)), queryAtLeastOnePermission: createReactiveSubscriptionFactory((permissions, scope) => hasAtLeastOnePermission(permissions, scope)), diff --git a/apps/meteor/client/providers/AvatarUrlProvider.tsx b/apps/meteor/client/providers/AvatarUrlProvider.tsx index cdf383dcf7d4..d043ad18b681 100644 --- a/apps/meteor/client/providers/AvatarUrlProvider.tsx +++ b/apps/meteor/client/providers/AvatarUrlProvider.tsx @@ -1,8 +1,7 @@ +import { AvatarUrlContext, useSetting } from '@rocket.chat/ui-contexts'; import React, { useMemo, FC } from 'react'; import { getURL } from '../../app/utils/lib/getURL'; -import { AvatarUrlContext } from '../contexts/AvatarUrlContext'; -import { useSetting } from '../contexts/SettingsContext'; import { roomCoordinator } from '../lib/rooms/roomCoordinator'; const AvatarUrlProvider: FC = ({ children }) => { diff --git a/apps/meteor/client/providers/CallProvider/CallProvider.tsx b/apps/meteor/client/providers/CallProvider/CallProvider.tsx index 0f560e859cfa..3b9825908bc0 100644 --- a/apps/meteor/client/providers/CallProvider/CallProvider.tsx +++ b/apps/meteor/client/providers/CallProvider/CallProvider.tsx @@ -1,5 +1,6 @@ import type { IVoipRoom, IUser } from '@rocket.chat/core-typings'; import { ICallerInfo } from '@rocket.chat/core-typings'; +import { useSetModal, useRoute, useUser, useSetting, useEndpoint, useStream } from '@rocket.chat/ui-contexts'; import { Random } from 'meteor/random'; import React, { useMemo, FC, useRef, useCallback, useEffect, useState } from 'react'; import { createPortal } from 'react-dom'; @@ -9,11 +10,6 @@ import { CustomSounds } from '../../../app/custom-sounds/client'; import { getUserPreference } from '../../../app/utils/client'; import { WrapUpCallModal } from '../../components/voip/modal/WrapUpCallModal'; import { CallContext, CallContextValue } from '../../contexts/CallContext'; -import { useSetModal } from '../../contexts/ModalContext'; -import { useRoute } from '../../contexts/RouterContext'; -import { useEndpoint, useStream } from '../../contexts/ServerContext'; -import { useSetting } from '../../contexts/SettingsContext'; -import { useUser } from '../../contexts/UserContext'; import { roomCoordinator } from '../../lib/rooms/roomCoordinator'; import { QueueAggregator } from '../../lib/voip/QueueAggregator'; import { useVoipClient } from './hooks/useVoipClient'; diff --git a/apps/meteor/client/providers/CallProvider/hooks/useVoipClient.ts b/apps/meteor/client/providers/CallProvider/hooks/useVoipClient.ts index 56ca3ad2c525..689fb1b0fd0d 100644 --- a/apps/meteor/client/providers/CallProvider/hooks/useVoipClient.ts +++ b/apps/meteor/client/providers/CallProvider/hooks/useVoipClient.ts @@ -1,11 +1,9 @@ import { IRegistrationInfo, WorkflowTypes } from '@rocket.chat/core-typings'; import { useSafely } from '@rocket.chat/fuselage-hooks'; +import { useUser, useSetting, useEndpoint, useStream } from '@rocket.chat/ui-contexts'; import { KJUR } from 'jsrsasign'; import { useEffect, useState } from 'react'; -import { useEndpoint, useStream } from '../../../contexts/ServerContext'; -import { useSetting } from '../../../contexts/SettingsContext'; -import { useUser } from '../../../contexts/UserContext'; import { SimpleVoipUser } from '../../../lib/voip/SimpleVoipUser'; import { VoIPUser } from '../../../lib/voip/VoIPUser'; import { useWebRtcServers } from './useWebRtcServers'; diff --git a/apps/meteor/client/providers/CallProvider/hooks/useWebRtcServers.ts b/apps/meteor/client/providers/CallProvider/hooks/useWebRtcServers.ts index 5de4a9838167..e843d0811bb2 100644 --- a/apps/meteor/client/providers/CallProvider/hooks/useWebRtcServers.ts +++ b/apps/meteor/client/providers/CallProvider/hooks/useWebRtcServers.ts @@ -1,6 +1,6 @@ +import { useSetting } from '@rocket.chat/ui-contexts'; import { useMemo } from 'react'; -import { useSetting } from '../../../contexts/SettingsContext'; import { IceServer } from '../definitions/IceServer'; import { parseStringToIceServers } from '../lib/parseStringToIceServers'; diff --git a/apps/meteor/client/providers/ConnectionStatusProvider.tsx b/apps/meteor/client/providers/ConnectionStatusProvider.tsx index 2763ce8eac48..f279042d5510 100644 --- a/apps/meteor/client/providers/ConnectionStatusProvider.tsx +++ b/apps/meteor/client/providers/ConnectionStatusProvider.tsx @@ -1,7 +1,7 @@ +import { ConnectionStatusContext, ConnectionStatusContextValue } from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; import React, { FC } from 'react'; -import { ConnectionStatusContext, ConnectionStatusContextValue } from '../contexts/ConnectionStatusContext'; import { useReactiveValue } from '../hooks/useReactiveValue'; const getValue = (): ConnectionStatusContextValue => ({ diff --git a/apps/meteor/client/providers/CustomSoundProvider.tsx b/apps/meteor/client/providers/CustomSoundProvider.tsx index 784ab15b356b..a7581df6a20a 100644 --- a/apps/meteor/client/providers/CustomSoundProvider.tsx +++ b/apps/meteor/client/providers/CustomSoundProvider.tsx @@ -1,7 +1,7 @@ +import { CustomSoundContext } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; import { CustomSounds } from '../../app/custom-sounds/client/lib/CustomSounds'; -import { CustomSoundContext } from '../contexts/CustomSoundContext'; const CustomSoundProvider: FC = ({ children }) => ; diff --git a/apps/meteor/client/providers/LayoutProvider.tsx b/apps/meteor/client/providers/LayoutProvider.tsx index df045e7c89a6..1eafe3000b31 100644 --- a/apps/meteor/client/providers/LayoutProvider.tsx +++ b/apps/meteor/client/providers/LayoutProvider.tsx @@ -1,10 +1,8 @@ import { useBreakpoints } from '@rocket.chat/fuselage-hooks'; -import React, { FC, useContext, useMemo } from 'react'; +import { LayoutContext, useQueryStringParameter, useSetting } from '@rocket.chat/ui-contexts'; +import React, { FC, useMemo } from 'react'; import { menu } from '../../app/ui-utils/client'; -import { LayoutContext, SizeLayout, LayoutContextValue } from '../contexts/LayoutContext'; -import { useQueryStringParameter } from '../contexts/RouterContext'; -import { useSetting } from '../contexts/SettingsContext'; const LayoutProvider: FC = ({ children }) => { const showTopNavbarEmbeddedLayout = Boolean(useSetting('UI_Show_top_navbar_embedded_layout')); @@ -35,9 +33,5 @@ const LayoutProvider: FC = ({ children }) => { /> ); }; -export default LayoutProvider; -export const useLayoutSizes = (): SizeLayout => useContext(LayoutContext).size; -export const useLayoutContextualBarExpanded = (): boolean => useContext(LayoutContext).contextualBarExpanded; -export const useLayoutContextualBarPosition = (): LayoutContextValue['contextualBarPosition'] => - useContext(LayoutContext).contextualBarPosition; +export default LayoutProvider; diff --git a/apps/meteor/client/providers/MeteorProvider.tsx b/apps/meteor/client/providers/MeteorProvider.tsx index 5eaa0f39837b..89aef340fdae 100644 --- a/apps/meteor/client/providers/MeteorProvider.tsx +++ b/apps/meteor/client/providers/MeteorProvider.tsx @@ -13,7 +13,6 @@ import RouterProvider from './RouterProvider'; import ServerProvider from './ServerProvider'; import SessionProvider from './SessionProvider'; import SettingsProvider from './SettingsProvider'; -import SidebarProvider from './SidebarProvider'; import ToastMessagesProvider from './ToastMessagesProvider'; import TooltipProvider from './TooltipProvider'; import TranslationProvider from './TranslationProvider'; @@ -25,31 +24,29 @@ const MeteorProvider: FC = ({ children }) => ( - - - - - - - - - - - - - {children} - - - - - - - - - - - - + + + + + + + + + + + + {children} + + + + + + + + + + + diff --git a/apps/meteor/client/providers/ModalProvider.tsx b/apps/meteor/client/providers/ModalProvider.tsx index 794da9a1a56d..e3bab9d296b3 100644 --- a/apps/meteor/client/providers/ModalProvider.tsx +++ b/apps/meteor/client/providers/ModalProvider.tsx @@ -1,9 +1,9 @@ +import { ModalContext } from '@rocket.chat/ui-contexts'; import React, { useState, useMemo, memo, ReactNode, useCallback, ReactElement } from 'react'; import { modal } from '../../app/ui-utils/client/lib/modal'; import ModalBackdrop from '../components/modal/ModalBackdrop'; import ModalPortal from '../components/modal/ModalPortal'; -import { ModalContext } from '../contexts/ModalContext'; import { useImperativeModal } from '../views/hooks/useImperativeModal'; type ModalProviderProps = { diff --git a/apps/meteor/client/providers/OmnichannelProvider.tsx b/apps/meteor/client/providers/OmnichannelProvider.tsx index 90ddc73e6ae6..16585aea1a02 100644 --- a/apps/meteor/client/providers/OmnichannelProvider.tsx +++ b/apps/meteor/client/providers/OmnichannelProvider.tsx @@ -1,17 +1,14 @@ import type { IOmnichannelAgent, IRoom } from '@rocket.chat/core-typings'; import { OmichannelRoutingConfig } from '@rocket.chat/core-typings'; import { useSafely } from '@rocket.chat/fuselage-hooks'; +import { useUser, useSetting, usePermission, useMethod } from '@rocket.chat/ui-contexts'; import React, { useState, useEffect, FC, useMemo, useCallback, memo, useRef } from 'react'; import { LivechatInquiry } from '../../app/livechat/client/collections/LivechatInquiry'; import { initializeLivechatInquiryStream } from '../../app/livechat/client/lib/stream/queueManager'; import { Notifications } from '../../app/notifications/client'; import { ClientLogger } from '../../lib/ClientLogger'; -import { usePermission } from '../contexts/AuthorizationContext'; import { OmnichannelContext, OmnichannelContextValue } from '../contexts/OmnichannelContext'; -import { useMethod } from '../contexts/ServerContext'; -import { useSetting } from '../contexts/SettingsContext'; -import { useUser } from '../contexts/UserContext'; import { useReactiveValue } from '../hooks/useReactiveValue'; const emptyContextValue: OmnichannelContextValue = { diff --git a/apps/meteor/client/providers/RouterProvider.tsx b/apps/meteor/client/providers/RouterProvider.tsx index 7efea20b01ce..b6d4b83cf260 100644 --- a/apps/meteor/client/providers/RouterProvider.tsx +++ b/apps/meteor/client/providers/RouterProvider.tsx @@ -1,10 +1,9 @@ +import { RouterContext, RouterContextValue } from '@rocket.chat/ui-contexts'; import { FlowRouter } from 'meteor/kadira:flow-router'; import { Tracker } from 'meteor/tracker'; import React, { FC } from 'react'; import { Subscription, Unsubscribe } from 'use-subscription'; -import { RouterContext, RouterContextValue } from '../contexts/RouterContext'; - const createSubscription = function (getValue: () => T): Subscription { let currentValue = Tracker.nonreactive(getValue); return { diff --git a/apps/meteor/client/providers/ServerProvider.tsx b/apps/meteor/client/providers/ServerProvider.tsx index dfa1acd4120c..1c5ec443195d 100644 --- a/apps/meteor/client/providers/ServerProvider.tsx +++ b/apps/meteor/client/providers/ServerProvider.tsx @@ -1,10 +1,10 @@ import { Serialized } from '@rocket.chat/core-typings'; import type { Method, PathFor, MatchPathPattern, OperationParams, OperationResult } from '@rocket.chat/rest-typings'; +import { ServerContext, ServerMethodName, ServerMethodParameters, ServerMethodReturn, UploadResult } from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; import React, { FC } from 'react'; import { Info as info, APIClient } from '../../app/utils/client'; -import { ServerContext, ServerMethodName, ServerMethodParameters, ServerMethodReturn, UploadResult } from '../contexts/ServerContext'; const absoluteUrl = (path: string): string => Meteor.absoluteUrl(path); diff --git a/apps/meteor/client/providers/SessionProvider.tsx b/apps/meteor/client/providers/SessionProvider.tsx index 565806577568..447cd93c806e 100644 --- a/apps/meteor/client/providers/SessionProvider.tsx +++ b/apps/meteor/client/providers/SessionProvider.tsx @@ -1,7 +1,7 @@ +import { SessionContext } from '@rocket.chat/ui-contexts'; import { Session } from 'meteor/session'; import React, { FC } from 'react'; -import { SessionContext } from '../contexts/SessionContext'; import { createReactiveSubscriptionFactory } from './createReactiveSubscriptionFactory'; const contextValue = { diff --git a/apps/meteor/client/providers/SettingsProvider.tsx b/apps/meteor/client/providers/SettingsProvider.tsx index 5356670e2f4e..0ed442dabc11 100644 --- a/apps/meteor/client/providers/SettingsProvider.tsx +++ b/apps/meteor/client/providers/SettingsProvider.tsx @@ -1,9 +1,7 @@ +import { SettingsContext, SettingsContextValue, useAtLeastOnePermission, useMethod } from '@rocket.chat/ui-contexts'; import { Tracker } from 'meteor/tracker'; import React, { useCallback, useEffect, useMemo, useState, FunctionComponent } from 'react'; -import { useAtLeastOnePermission } from '../contexts/AuthorizationContext'; -import { useMethod } from '../contexts/ServerContext'; -import { SettingsContext, SettingsContextValue } from '../contexts/SettingsContext'; import { PrivateSettingsCachedCollection } from '../lib/settings/PrivateSettingsCachedCollection'; import { PublicSettingsCachedCollection } from '../lib/settings/PublicSettingsCachedCollection'; import { createReactiveSubscriptionFactory } from './createReactiveSubscriptionFactory'; diff --git a/apps/meteor/client/providers/SidebarProvider.tsx b/apps/meteor/client/providers/SidebarProvider.tsx deleted file mode 100644 index 7142b01cc801..000000000000 --- a/apps/meteor/client/providers/SidebarProvider.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React, { FC } from 'react'; - -import { menu } from '../../app/ui-utils/client'; -import { SidebarContext } from '../contexts/SidebarContext'; -import { useReactiveValue } from '../hooks/useReactiveValue'; - -const getOpen = (): boolean => menu.isOpen(); - -const setOpen = (open: boolean | ((isOpen: boolean) => boolean)): void => { - if (typeof open === 'function') { - open = open(menu.isOpen()); - } - - return open ? menu.open() : menu.close(); -}; - -const SidebarProvider: FC = ({ children }) => ( - (getOpen), setOpen]} /> -); - -export default SidebarProvider; diff --git a/apps/meteor/client/providers/ToastMessagesProvider.tsx b/apps/meteor/client/providers/ToastMessagesProvider.tsx index 7c7be1dd4eef..509dabece81e 100644 --- a/apps/meteor/client/providers/ToastMessagesProvider.tsx +++ b/apps/meteor/client/providers/ToastMessagesProvider.tsx @@ -1,7 +1,7 @@ +import { ToastMessagesContext } from '@rocket.chat/ui-contexts'; import React, { FC, useEffect } from 'react'; import toastr from 'toastr'; -import { ToastMessagesContext } from '../contexts/ToastMessagesContext'; import { dispatchToastMessage, subscribeToToastMessages } from '../lib/toast'; import { handleError } from '../lib/utils/handleError'; diff --git a/apps/meteor/client/providers/TooltipProvider.tsx b/apps/meteor/client/providers/TooltipProvider.tsx index 16490bc14b44..e21259f5109a 100644 --- a/apps/meteor/client/providers/TooltipProvider.tsx +++ b/apps/meteor/client/providers/TooltipProvider.tsx @@ -1,9 +1,9 @@ import { useMediaQuery } from '@rocket.chat/fuselage-hooks'; +import { TooltipContext } from '@rocket.chat/ui-contexts'; import React, { FC, useEffect, useState, useMemo, ReactNode, useRef, memo } from 'react'; import { TooltipComponent } from '../components/TooltipComponent'; import TooltipPortal from '../components/TooltipPortal'; -import { TooltipContext } from '../contexts/TooltipContext'; const TooltipProvider: FC = ({ children }) => { const lastAnchor = useRef(); diff --git a/apps/meteor/client/providers/TranslationProvider.js b/apps/meteor/client/providers/TranslationProvider.js index 60a6bfb8177c..3e4ef59b46d6 100644 --- a/apps/meteor/client/providers/TranslationProvider.js +++ b/apps/meteor/client/providers/TranslationProvider.js @@ -1,7 +1,7 @@ +import { TranslationContext } from '@rocket.chat/ui-contexts'; import { TAPi18n, TAPi18next } from 'meteor/rocketchat:tap-i18n'; import React, { useMemo } from 'react'; -import { TranslationContext } from '../contexts/TranslationContext'; import { useReactiveValue } from '../hooks/useReactiveValue'; const createTranslateFunction = (language) => { diff --git a/apps/meteor/client/providers/UserProvider.tsx b/apps/meteor/client/providers/UserProvider.tsx index 8c4064bb2b90..2f7cb37a784f 100644 --- a/apps/meteor/client/providers/UserProvider.tsx +++ b/apps/meteor/client/providers/UserProvider.tsx @@ -1,11 +1,11 @@ import type { IRoom, ISubscription, IUser } from '@rocket.chat/core-typings'; +import { UserContext } from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; import React, { useMemo, FC } from 'react'; import { Subscriptions, Rooms } from '../../app/models/client'; import { getUserPreference } from '../../app/utils/client'; import { callbacks } from '../../lib/callbacks'; -import { UserContext } from '../contexts/UserContext'; import { useReactiveValue } from '../hooks/useReactiveValue'; import { createReactiveSubscriptionFactory } from './createReactiveSubscriptionFactory'; diff --git a/apps/meteor/client/sidebar/RoomList/RoomList.js b/apps/meteor/client/sidebar/RoomList/RoomList.js index 5f34289e7467..136bff2ac01b 100644 --- a/apps/meteor/client/sidebar/RoomList/RoomList.js +++ b/apps/meteor/client/sidebar/RoomList/RoomList.js @@ -1,11 +1,9 @@ import { Box } from '@rocket.chat/fuselage'; import { useResizeObserver } from '@rocket.chat/fuselage-hooks'; +import { useSession, useUserPreference, useUserId, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useRef, useEffect, useMemo } from 'react'; import { Virtuoso } from 'react-virtuoso'; -import { useSession } from '../../contexts/SessionContext'; -import { useTranslation } from '../../contexts/TranslationContext'; -import { useUserPreference, useUserId } from '../../contexts/UserContext'; import { useAvatarTemplate } from '../hooks/useAvatarTemplate'; import { usePreventDefault } from '../hooks/usePreventDefault'; import { useRoomList } from '../hooks/useRoomList'; diff --git a/apps/meteor/client/sidebar/RoomList/SideBarItemTemplateWithData.js b/apps/meteor/client/sidebar/RoomList/SideBarItemTemplateWithData.js index 8efa329a3779..4cccb6cd177d 100644 --- a/apps/meteor/client/sidebar/RoomList/SideBarItemTemplateWithData.js +++ b/apps/meteor/client/sidebar/RoomList/SideBarItemTemplateWithData.js @@ -1,8 +1,8 @@ import { Badge, Sidebar } from '@rocket.chat/fuselage'; +import { useLayout } from '@rocket.chat/ui-contexts'; import React, { memo } from 'react'; import { RoomIcon } from '../../components/RoomIcon'; -import { useLayout } from '../../contexts/LayoutContext'; import { roomCoordinator } from '../../lib/rooms/roomCoordinator'; import RoomMenu from '../RoomMenu'; import { normalizeSidebarMessage } from './normalizeSidebarMessage'; diff --git a/apps/meteor/client/sidebar/RoomMenu.js b/apps/meteor/client/sidebar/RoomMenu.js index 93ed2156fd8e..5e703f011e23 100644 --- a/apps/meteor/client/sidebar/RoomMenu.js +++ b/apps/meteor/client/sidebar/RoomMenu.js @@ -1,18 +1,20 @@ import { Option, Menu } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { + useSetModal, + useToastMessageDispatch, + useRoute, + useUserSubscription, + useSetting, + usePermission, + useMethod, + useTranslation, +} from '@rocket.chat/ui-contexts'; import React, { memo, useMemo } from 'react'; import { RoomManager } from '../../app/ui-utils/client/lib/RoomManager'; import { UiTextContext } from '../../definition/IRoomTypeConfig'; import { GenericModalDoNotAskAgain } from '../components/GenericModal'; -import { usePermission } from '../contexts/AuthorizationContext'; -import { useSetModal } from '../contexts/ModalContext'; -import { useRoute } from '../contexts/RouterContext'; -import { useMethod } from '../contexts/ServerContext'; -import { useSetting } from '../contexts/SettingsContext'; -import { useToastMessageDispatch } from '../contexts/ToastMessagesContext'; -import { useTranslation } from '../contexts/TranslationContext'; -import { useUserSubscription } from '../contexts/UserContext'; import { useDontAskAgain } from '../hooks/useDontAskAgain'; import { roomCoordinator } from '../lib/rooms/roomCoordinator'; import WarningModal from '../views/admin/apps/WarningModal'; diff --git a/apps/meteor/client/sidebar/Sidebar.stories.tsx b/apps/meteor/client/sidebar/Sidebar.stories.tsx index 8d58636ef6f9..8a9e70d9c20e 100644 --- a/apps/meteor/client/sidebar/Sidebar.stories.tsx +++ b/apps/meteor/client/sidebar/Sidebar.stories.tsx @@ -1,9 +1,9 @@ import type { ISetting, ISubscription } from '@rocket.chat/core-typings'; +import { UserContext, SettingsContext } from '@rocket.chat/ui-contexts'; import { Meta, Story } from '@storybook/react'; +import type { ObjectId } from 'mongodb'; import React, { ContextType } from 'react'; -import { SettingsContext } from '../contexts/SettingsContext'; -import { UserContext } from '../contexts/UserContext'; import RoomList from './RoomList/index'; import Header from './header'; @@ -87,7 +87,7 @@ const userContextValue: ContextType = { roles: ['admin'], type: 'user', }, - queryPreference: (pref: string | Mongo.ObjectID, defaultValue: T) => ({ + queryPreference: (pref: string | ObjectId, defaultValue: T) => ({ getCurrentValue: () => (typeof pref === 'string' ? (userPreferences[pref] as T) : defaultValue), subscribe: () => () => undefined, }), diff --git a/apps/meteor/client/sidebar/footer/voip/index.tsx b/apps/meteor/client/sidebar/footer/voip/index.tsx index e7ccd217afdb..29ba87935ac1 100644 --- a/apps/meteor/client/sidebar/footer/voip/index.tsx +++ b/apps/meteor/client/sidebar/footer/voip/index.tsx @@ -1,3 +1,4 @@ +import { useEndpoint, useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement, useCallback, useMemo, useState } from 'react'; import { @@ -10,8 +11,6 @@ import { useQueueName, useWrapUpModal, } from '../../../contexts/CallContext'; -import { useEndpoint } from '../../../contexts/ServerContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { VoipFooter as VoipFooterComponent } from './VoipFooter'; export const VoipFooter = (): ReactElement | null => { diff --git a/apps/meteor/client/sidebar/header/CreateChannel.js b/apps/meteor/client/sidebar/header/CreateChannel.js index d2a913f0472b..f5a2f25dec49 100644 --- a/apps/meteor/client/sidebar/header/CreateChannel.js +++ b/apps/meteor/client/sidebar/header/CreateChannel.js @@ -1,11 +1,9 @@ import { Box, Modal, ButtonGroup, Button, TextInput, Icon, Field, ToggleSwitch, FieldGroup } from '@rocket.chat/fuselage'; import { useDebouncedCallback } from '@rocket.chat/fuselage-hooks'; +import { useSetting, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useEffect, useMemo, useState } from 'react'; import UserAutoCompleteMultiple from '../../components/UserAutoCompleteMultiple'; -import { useMethod } from '../../contexts/ServerContext'; -import { useSetting } from '../../contexts/SettingsContext'; -import { useTranslation } from '../../contexts/TranslationContext'; const CreateChannel = ({ values, diff --git a/apps/meteor/client/sidebar/header/CreateChannelWithData.js b/apps/meteor/client/sidebar/header/CreateChannelWithData.js index e5f820126627..346f2ab1d15a 100644 --- a/apps/meteor/client/sidebar/header/CreateChannelWithData.js +++ b/apps/meteor/client/sidebar/header/CreateChannelWithData.js @@ -1,8 +1,7 @@ import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useSetting, usePermission } from '@rocket.chat/ui-contexts'; import React, { memo, useCallback, useMemo } from 'react'; -import { usePermission } from '../../contexts/AuthorizationContext'; -import { useSetting } from '../../contexts/SettingsContext'; import { useEndpointActionExperimental } from '../../hooks/useEndpointActionExperimental'; import { useForm } from '../../hooks/useForm'; import { goToRoomById } from '../../lib/utils/goToRoomById'; diff --git a/apps/meteor/client/sidebar/header/CreateDirectMessage.tsx b/apps/meteor/client/sidebar/header/CreateDirectMessage.tsx index 5efd90574c7f..566360cc1520 100644 --- a/apps/meteor/client/sidebar/header/CreateDirectMessage.tsx +++ b/apps/meteor/client/sidebar/header/CreateDirectMessage.tsx @@ -1,10 +1,10 @@ import type { IUser } from '@rocket.chat/core-typings'; import { Box, Modal, ButtonGroup, Button } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC, useState, memo } from 'react'; import UserAutoCompleteMultiple from '../../components/UserAutoCompleteMultiple'; -import { useTranslation } from '../../contexts/TranslationContext'; import { useEndpointActionExperimental } from '../../hooks/useEndpointActionExperimental'; import { goToRoomById } from '../../lib/utils/goToRoomById'; diff --git a/apps/meteor/client/sidebar/header/EditStatusModal.tsx b/apps/meteor/client/sidebar/header/EditStatusModal.tsx index 2cfdd611d62b..16ec76b24bd5 100644 --- a/apps/meteor/client/sidebar/header/EditStatusModal.tsx +++ b/apps/meteor/client/sidebar/header/EditStatusModal.tsx @@ -1,14 +1,11 @@ import type { IUser } from '@rocket.chat/core-typings'; import { Field, TextInput, FieldGroup, Modal, Icon, ButtonGroup, Button } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useToastMessageDispatch, useSetting, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement, useState, ChangeEvent, useCallback } from 'react'; import { USER_STATUS_TEXT_MAX_LENGTH } from '../../components/UserStatus'; import UserStatusMenu from '../../components/UserStatusMenu'; -import { useMethod } from '../../contexts/ServerContext'; -import { useSetting } from '../../contexts/SettingsContext'; -import { useToastMessageDispatch } from '../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../contexts/TranslationContext'; type EditStatusModalProps = { onClose: () => void; diff --git a/apps/meteor/client/sidebar/header/UserAvatarButton.tsx b/apps/meteor/client/sidebar/header/UserAvatarButton.tsx index 560c646fc418..dbe98f95fce9 100644 --- a/apps/meteor/client/sidebar/header/UserAvatarButton.tsx +++ b/apps/meteor/client/sidebar/header/UserAvatarButton.tsx @@ -1,12 +1,12 @@ import type { IUser } from '@rocket.chat/core-typings'; import { css } from '@rocket.chat/css-in-js'; import { Box, Dropdown } from '@rocket.chat/fuselage'; +import { useUser } from '@rocket.chat/ui-contexts'; import React, { memo, useRef, ReactElement } from 'react'; import { createPortal } from 'react-dom'; import { UserStatus } from '../../components/UserStatus'; import UserAvatar from '../../components/avatar/UserAvatar'; -import { useUser } from '../../contexts/UserContext'; import UserDropdown from './UserDropdown'; import { useDropdownVisibility } from './hooks/useDropdownVisibility'; diff --git a/apps/meteor/client/sidebar/header/UserDropdown.tsx b/apps/meteor/client/sidebar/header/UserDropdown.tsx index bde32a2dda18..623b85ba7dd5 100644 --- a/apps/meteor/client/sidebar/header/UserDropdown.tsx +++ b/apps/meteor/client/sidebar/header/UserDropdown.tsx @@ -2,6 +2,7 @@ import type { IUser } from '@rocket.chat/core-typings'; import { UserStatus as UserStatusEnum, ValueOf } from '@rocket.chat/core-typings'; import { Box, Margins, Option } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useLayout, useRoute, useLogout, useSetting, useAtLeastOnePermission, useTranslation } from '@rocket.chat/ui-contexts'; import { FlowRouter } from 'meteor/kadira:flow-router'; import React, { ReactElement } from 'react'; @@ -11,12 +12,6 @@ import { callbacks } from '../../../lib/callbacks'; import MarkdownText from '../../components/MarkdownText'; import { UserStatus } from '../../components/UserStatus'; import UserAvatar from '../../components/avatar/UserAvatar'; -import { useAtLeastOnePermission } from '../../contexts/AuthorizationContext'; -import { useLayout } from '../../contexts/LayoutContext'; -import { useRoute } from '../../contexts/RouterContext'; -import { useSetting } from '../../contexts/SettingsContext'; -import { useTranslation } from '../../contexts/TranslationContext'; -import { useLogout } from '../../contexts/UserContext'; import { useReactiveValue } from '../../hooks/useReactiveValue'; import { useUserDisplayName } from '../../hooks/useUserDisplayName'; import { imperativeModal } from '../../lib/imperativeModal'; diff --git a/apps/meteor/client/sidebar/header/actions/CreateRoom.js b/apps/meteor/client/sidebar/header/actions/CreateRoom.js index 37a6c024de6d..c1ee83a9590c 100644 --- a/apps/meteor/client/sidebar/header/actions/CreateRoom.js +++ b/apps/meteor/client/sidebar/header/actions/CreateRoom.js @@ -1,8 +1,8 @@ import { Box, Sidebar, Dropdown } from '@rocket.chat/fuselage'; +import { useAtLeastOnePermission } from '@rocket.chat/ui-contexts'; import React, { useRef } from 'react'; import { createPortal } from 'react-dom'; -import { useAtLeastOnePermission } from '../../../contexts/AuthorizationContext'; import { useDropdownVisibility } from '../hooks/useDropdownVisibility'; import CreateRoomList from './CreateRoomList'; diff --git a/apps/meteor/client/sidebar/header/actions/CreateRoomList.js b/apps/meteor/client/sidebar/header/actions/CreateRoomList.js index c8d8d8aeaa2c..3ad249407f05 100644 --- a/apps/meteor/client/sidebar/header/actions/CreateRoomList.js +++ b/apps/meteor/client/sidebar/header/actions/CreateRoomList.js @@ -1,14 +1,11 @@ import { OptionTitle } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useSetModal, useSetting, useAtLeastOnePermission, useTranslation } from '@rocket.chat/ui-contexts'; import React from 'react'; import { popover } from '../../../../app/ui-utils/client'; import CreateDiscussion from '../../../components/CreateDiscussion'; import ListItem from '../../../components/Sidebar/ListItem'; -import { useAtLeastOnePermission } from '../../../contexts/AuthorizationContext'; -import { useSetModal } from '../../../contexts/ModalContext'; -import { useSetting } from '../../../contexts/SettingsContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import CreateTeamModal from '../../../views/teams/CreateTeamModal'; import CreateChannelWithData from '../CreateChannelWithData'; import CreateDirectMessage from '../CreateDirectMessage'; diff --git a/apps/meteor/client/sidebar/header/actions/Directory.js b/apps/meteor/client/sidebar/header/actions/Directory.js index 4b1a03cf0157..ba6f67f9b7fe 100644 --- a/apps/meteor/client/sidebar/header/actions/Directory.js +++ b/apps/meteor/client/sidebar/header/actions/Directory.js @@ -1,10 +1,8 @@ import { Sidebar } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useLayout, useRoute } from '@rocket.chat/ui-contexts'; import React from 'react'; -import { useLayout } from '../../../contexts/LayoutContext'; -import { useRoute } from '../../../contexts/RouterContext'; - const Directory = (props) => { const directoryRoute = useRoute('directory'); const { sidebar } = useLayout(); diff --git a/apps/meteor/client/sidebar/header/actions/Home.js b/apps/meteor/client/sidebar/header/actions/Home.js index 4b308af1aaeb..405ed61d2552 100644 --- a/apps/meteor/client/sidebar/header/actions/Home.js +++ b/apps/meteor/client/sidebar/header/actions/Home.js @@ -1,11 +1,8 @@ import { Sidebar } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useLayout, useRoute, useSetting } from '@rocket.chat/ui-contexts'; import React from 'react'; -import { useLayout } from '../../../contexts/LayoutContext'; -import { useRoute } from '../../../contexts/RouterContext'; -import { useSetting } from '../../../contexts/SettingsContext'; - const Home = (props) => { const homeRoute = useRoute('home'); const { sidebar } = useLayout(); diff --git a/apps/meteor/client/sidebar/header/actions/Login.js b/apps/meteor/client/sidebar/header/actions/Login.js index 47ca074ff484..6eb6a0737080 100644 --- a/apps/meteor/client/sidebar/header/actions/Login.js +++ b/apps/meteor/client/sidebar/header/actions/Login.js @@ -1,9 +1,7 @@ import { Sidebar } from '@rocket.chat/fuselage'; +import { useSessionDispatch, useTranslation } from '@rocket.chat/ui-contexts'; import React from 'react'; -import { useSessionDispatch } from '../../../contexts/SessionContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; - const Login = (props) => { const setForceLogin = useSessionDispatch('forceLogin'); const t = useTranslation(); diff --git a/apps/meteor/client/sidebar/header/index.js b/apps/meteor/client/sidebar/header/index.js index 524071d4e0e6..30ad7be3f1a5 100644 --- a/apps/meteor/client/sidebar/header/index.js +++ b/apps/meteor/client/sidebar/header/index.js @@ -1,8 +1,7 @@ import { Sidebar } from '@rocket.chat/fuselage'; +import { useUser, useTranslation } from '@rocket.chat/ui-contexts'; import React, { memo } from 'react'; -import { useTranslation } from '../../contexts/TranslationContext'; -import { useUser } from '../../contexts/UserContext'; import { useSidebarPaletteColor } from '../hooks/useSidebarPaletteColor'; import UserAvatarButton from './UserAvatarButton'; import CreateRoom from './actions/CreateRoom'; diff --git a/apps/meteor/client/sidebar/hooks/useAvatarTemplate.tsx b/apps/meteor/client/sidebar/hooks/useAvatarTemplate.tsx index f8b1c9c177bd..09836e19250b 100644 --- a/apps/meteor/client/sidebar/hooks/useAvatarTemplate.tsx +++ b/apps/meteor/client/sidebar/hooks/useAvatarTemplate.tsx @@ -1,8 +1,8 @@ import type { IRoom } from '@rocket.chat/core-typings'; +import { useUserPreference } from '@rocket.chat/ui-contexts'; import React, { ReactNode, useMemo } from 'react'; import RoomAvatar from '../../components/avatar/RoomAvatar'; -import { useUserPreference } from '../../contexts/UserContext'; export const useAvatarTemplate = ( sidebarViewMode?: 'extended' | 'medium' | 'condensed', diff --git a/apps/meteor/client/sidebar/hooks/useQueryOptions.js b/apps/meteor/client/sidebar/hooks/useQueryOptions.js index 8ff69f7b6bb4..6bd31aad23f2 100644 --- a/apps/meteor/client/sidebar/hooks/useQueryOptions.js +++ b/apps/meteor/client/sidebar/hooks/useQueryOptions.js @@ -1,8 +1,6 @@ +import { useUserPreference, useSetting } from '@rocket.chat/ui-contexts'; import { useMemo } from 'react'; -import { useSetting } from '../../contexts/SettingsContext'; -import { useUserPreference } from '../../contexts/UserContext'; - export const useQueryOptions = () => { const sortBy = useUserPreference('sidebarSortby'); const showRealName = useSetting('UI_Use_Real_Name'); diff --git a/apps/meteor/client/sidebar/hooks/useRoomList.ts b/apps/meteor/client/sidebar/hooks/useRoomList.ts index 7e7fcc43fc17..3abc6ce70b4c 100644 --- a/apps/meteor/client/sidebar/hooks/useRoomList.ts +++ b/apps/meteor/client/sidebar/hooks/useRoomList.ts @@ -1,10 +1,10 @@ import type { IRoom, ISubscription } from '@rocket.chat/core-typings'; import { useDebouncedState } from '@rocket.chat/fuselage-hooks'; +import { useUserPreference, useUserSubscriptions, useSetting } from '@rocket.chat/ui-contexts'; import { useEffect } from 'react'; -import { useQueuedInquiries, useOmnichannelEnabled } from '../../contexts/OmnichannelContext'; -import { useSetting } from '../../contexts/SettingsContext'; -import { useUserPreference, useUserSubscriptions } from '../../contexts/UserContext'; +import { useOmnichannelEnabled } from '../../hooks/omnichannel/useOmnichannelEnabled'; +import { useQueuedInquiries } from '../../hooks/omnichannel/useQueuedInquiries'; import { useQueryOptions } from './useQueryOptions'; const query = { open: { $ne: false } }; diff --git a/apps/meteor/client/sidebar/hooks/useSidebarPaletteColor.js b/apps/meteor/client/sidebar/hooks/useSidebarPaletteColor.js index 3d935e154a48..c824c95b5b8a 100644 --- a/apps/meteor/client/sidebar/hooks/useSidebarPaletteColor.js +++ b/apps/meteor/client/sidebar/hooks/useSidebarPaletteColor.js @@ -1,7 +1,7 @@ import colors from '@rocket.chat/fuselage-tokens/colors'; +import { useSettings } from '@rocket.chat/ui-contexts'; import { useLayoutEffect, useEffect, useMemo } from 'react'; -import { useSettings } from '../../contexts/SettingsContext'; import { isIE11 } from '../../lib/utils/isIE11'; const oldPallet = { diff --git a/apps/meteor/client/sidebar/hooks/useTemplateByViewMode.js b/apps/meteor/client/sidebar/hooks/useTemplateByViewMode.js index a06c435dafd0..2e518ee2dec8 100644 --- a/apps/meteor/client/sidebar/hooks/useTemplateByViewMode.js +++ b/apps/meteor/client/sidebar/hooks/useTemplateByViewMode.js @@ -1,6 +1,6 @@ +import { useUserPreference } from '@rocket.chat/ui-contexts'; import { useMemo } from 'react'; -import { useUserPreference } from '../../contexts/UserContext'; import Condensed from '../Item/Condensed'; import Extended from '../Item/Extended'; import Medium from '../Item/Medium'; diff --git a/apps/meteor/client/sidebar/search/SearchList.js b/apps/meteor/client/sidebar/search/SearchList.js index 6eeb6a4473b3..4544dcdd68e5 100644 --- a/apps/meteor/client/sidebar/search/SearchList.js +++ b/apps/meteor/client/sidebar/search/SearchList.js @@ -2,14 +2,12 @@ import { css } from '@rocket.chat/css-in-js'; import { Sidebar, TextInput, Box, Icon } from '@rocket.chat/fuselage'; import { useMutableCallback, useDebouncedValue, useStableArray, useAutoFocus, useUniqueId } from '@rocket.chat/fuselage-hooks'; import { escapeRegExp } from '@rocket.chat/string-helpers'; +import { useUserPreference, useUserSubscriptions, useSetting, useTranslation } from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; import React, { forwardRef, useState, useMemo, useEffect, useRef } from 'react'; import { Virtuoso } from 'react-virtuoso'; import tinykeys from 'tinykeys'; -import { useSetting } from '../../contexts/SettingsContext'; -import { useTranslation } from '../../contexts/TranslationContext'; -import { useUserPreference, useUserSubscriptions } from '../../contexts/UserContext'; import { AsyncStatePhase } from '../../hooks/useAsyncState'; import { useMethodData } from '../../hooks/useMethodData'; import { useAvatarTemplate } from '../hooks/useAvatarTemplate'; diff --git a/apps/meteor/client/sidebar/sections/OmnichannelSection.tsx b/apps/meteor/client/sidebar/sections/OmnichannelSection.tsx index dacd2cf12fc4..117c913f27eb 100644 --- a/apps/meteor/client/sidebar/sections/OmnichannelSection.tsx +++ b/apps/meteor/client/sidebar/sections/OmnichannelSection.tsx @@ -1,15 +1,11 @@ import { Box, Sidebar } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useLayout, useToastMessageDispatch, useRoute, usePermission, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { memo, ReactElement } from 'react'; -import { usePermission } from '../../contexts/AuthorizationContext'; import { useIsCallEnabled } from '../../contexts/CallContext'; -import { useLayout } from '../../contexts/LayoutContext'; -import { useOmnichannelShowQueueLink, useOmnichannelAgentAvailable } from '../../contexts/OmnichannelContext'; -import { useRoute } from '../../contexts/RouterContext'; -import { useMethod } from '../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../contexts/TranslationContext'; +import { useOmnichannelAgentAvailable } from '../../hooks/omnichannel/useOmnichannelAgentAvailable'; +import { useOmnichannelShowQueueLink } from '../../hooks/omnichannel/useOmnichannelShowQueueLink'; import { OmnichannelCallToggle } from './components/OmnichannelCallToggle'; const OmnichannelSection = (props: typeof Box): ReactElement => { diff --git a/apps/meteor/client/sidebar/sections/components/OmnichannelCallToggleError.tsx b/apps/meteor/client/sidebar/sections/components/OmnichannelCallToggleError.tsx index 4ec543a670f9..ecaa9684e67c 100644 --- a/apps/meteor/client/sidebar/sections/components/OmnichannelCallToggleError.tsx +++ b/apps/meteor/client/sidebar/sections/components/OmnichannelCallToggleError.tsx @@ -1,8 +1,7 @@ import { Sidebar } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; - export const OmnichannelCallToggleError = (): ReactElement => { const t = useTranslation(); return ; diff --git a/apps/meteor/client/sidebar/sections/components/OmnichannelCallToggleLoading.tsx b/apps/meteor/client/sidebar/sections/components/OmnichannelCallToggleLoading.tsx index d4362c393814..61b08a1b2926 100644 --- a/apps/meteor/client/sidebar/sections/components/OmnichannelCallToggleLoading.tsx +++ b/apps/meteor/client/sidebar/sections/components/OmnichannelCallToggleLoading.tsx @@ -1,8 +1,7 @@ import { Sidebar } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; - export const OmnichannelCallToggleLoading = (): ReactElement => { const t = useTranslation(); return ; diff --git a/apps/meteor/client/sidebar/sections/components/OmnichannelCallToggleReady.tsx b/apps/meteor/client/sidebar/sections/components/OmnichannelCallToggleReady.tsx index 43d335214a0c..0b1da0fccb50 100644 --- a/apps/meteor/client/sidebar/sections/components/OmnichannelCallToggleReady.tsx +++ b/apps/meteor/client/sidebar/sections/components/OmnichannelCallToggleReady.tsx @@ -1,9 +1,9 @@ import { Sidebar } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement, useEffect, useState } from 'react'; import { useCallClient, useCallerInfo, useCallActions } from '../../../contexts/CallContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; type NetworkState = 'online' | 'offline'; export const OmnichannelCallToggleReady = (): ReactElement => { diff --git a/apps/meteor/client/startup/contextualBar/exportMessages.ts b/apps/meteor/client/startup/contextualBar/exportMessages.ts index 6a8dafabaa84..8422f7b482cc 100644 --- a/apps/meteor/client/startup/contextualBar/exportMessages.ts +++ b/apps/meteor/client/startup/contextualBar/exportMessages.ts @@ -1,6 +1,6 @@ +import { usePermission } from '@rocket.chat/ui-contexts'; import { useMemo, lazy, LazyExoticComponent, FC } from 'react'; -import { usePermission } from '../../contexts/AuthorizationContext'; import { addAction } from '../../views/room/lib/Toolbox'; addAction('export-messages', ({ room }) => { diff --git a/apps/meteor/client/stories/contexts/ModalContextMock.tsx b/apps/meteor/client/stories/contexts/ModalContextMock.tsx index 3d0a03254cfd..7abc158dcc1d 100644 --- a/apps/meteor/client/stories/contexts/ModalContextMock.tsx +++ b/apps/meteor/client/stories/contexts/ModalContextMock.tsx @@ -1,8 +1,7 @@ +import { ModalContext } from '@rocket.chat/ui-contexts'; import { action } from '@storybook/addon-actions'; import React, { ContextType, ReactElement, ReactNode, useContext, useMemo } from 'react'; -import { ModalContext } from '../../contexts/ModalContext'; - const logAction = action('ModalContext'); type ModalContextMockProps = { diff --git a/apps/meteor/client/stories/contexts/RouterContextMock.tsx b/apps/meteor/client/stories/contexts/RouterContextMock.tsx index 8ee0c2553f23..3da1b7cb407a 100644 --- a/apps/meteor/client/stories/contexts/RouterContextMock.tsx +++ b/apps/meteor/client/stories/contexts/RouterContextMock.tsx @@ -1,8 +1,7 @@ +import { RouterContext } from '@rocket.chat/ui-contexts'; import { action } from '@storybook/addon-actions'; import React, { ContextType, ReactElement, ReactNode, useContext, useMemo } from 'react'; -import { RouterContext } from '../../contexts/RouterContext'; - const logAction = action('RouterContext'); type RouterContextMockProps = { diff --git a/apps/meteor/client/stories/contexts/ServerContextMock.tsx b/apps/meteor/client/stories/contexts/ServerContextMock.tsx index 195465764e40..0a01e883ace2 100644 --- a/apps/meteor/client/stories/contexts/ServerContextMock.tsx +++ b/apps/meteor/client/stories/contexts/ServerContextMock.tsx @@ -1,11 +1,10 @@ import { Serialized } from '@rocket.chat/core-typings'; import type { MatchPathPattern, Method, OperationParams, OperationResult, Path, PathFor } from '@rocket.chat/rest-typings'; +import { ServerContext, ServerMethodName, ServerMethodParameters, ServerMethodReturn, UploadResult } from '@rocket.chat/ui-contexts'; import { action } from '@storybook/addon-actions'; import { pathToRegexp } from 'path-to-regexp'; import React, { ContextType, ReactElement, ReactNode, useContext, useMemo } from 'react'; -import { ServerContext, ServerMethodName, ServerMethodParameters, ServerMethodReturn, UploadResult } from '../../contexts/ServerContext'; - const logAction = action('ServerContext'); const randomDelay = (): Promise => new Promise((resolve) => setTimeout(resolve, Math.random() * 1000)); diff --git a/apps/meteor/client/stories/contexts/TranslationContextMock.tsx b/apps/meteor/client/stories/contexts/TranslationContextMock.tsx index 5d88fbb22505..d4ffd1459154 100644 --- a/apps/meteor/client/stories/contexts/TranslationContextMock.tsx +++ b/apps/meteor/client/stories/contexts/TranslationContextMock.tsx @@ -1,8 +1,7 @@ +import { TranslationContext } from '@rocket.chat/ui-contexts'; import i18next from 'i18next'; import React, { ContextType, ReactElement, ReactNode, useContext, useMemo } from 'react'; -import { TranslationContext } from '../../contexts/TranslationContext'; - type TranslationContextMockProps = { children: ReactNode; }; diff --git a/apps/meteor/client/views/InfoPanel/RetentionPolicyCallout.tsx b/apps/meteor/client/views/InfoPanel/RetentionPolicyCallout.tsx index 6ce9088700fb..c97e0bb07567 100644 --- a/apps/meteor/client/views/InfoPanel/RetentionPolicyCallout.tsx +++ b/apps/meteor/client/views/InfoPanel/RetentionPolicyCallout.tsx @@ -1,7 +1,7 @@ import { Callout } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; -import { useTranslation } from '../../contexts/TranslationContext'; import { useFormattedRelativeTime } from '../../hooks/useFormattedRelativeTime'; type RetentionPolicyCalloutProps = { diff --git a/apps/meteor/client/views/account/AccountIntegrationsPage.tsx b/apps/meteor/client/views/account/AccountIntegrationsPage.tsx index 2f66b23679ff..4fd35110f3ff 100644 --- a/apps/meteor/client/views/account/AccountIntegrationsPage.tsx +++ b/apps/meteor/client/views/account/AccountIntegrationsPage.tsx @@ -1,12 +1,10 @@ import type { IWebdavAccount } from '@rocket.chat/core-typings'; import { Box, Select, SelectOption, Field, Button } from '@rocket.chat/fuselage'; +import { useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useMemo, useCallback, ReactElement } from 'react'; import { WebdavAccounts } from '../../../app/models/client'; import Page from '../../components/Page'; -import { useMethod } from '../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../contexts/TranslationContext'; import { useForm } from '../../hooks/useForm'; import { useReactiveValue } from '../../hooks/useReactiveValue'; diff --git a/apps/meteor/client/views/account/AccountProfileForm.js b/apps/meteor/client/views/account/AccountProfileForm.js index c54e67296910..cf26eab7d4fb 100644 --- a/apps/meteor/client/views/account/AccountProfileForm.js +++ b/apps/meteor/client/views/account/AccountProfileForm.js @@ -12,6 +12,7 @@ import { Margins, } from '@rocket.chat/fuselage'; import { useDebouncedCallback, useSafely } from '@rocket.chat/fuselage-hooks'; +import { useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback, useMemo, useEffect, useState } from 'react'; import { validateEmail } from '../../../lib/emailValidator'; @@ -20,9 +21,6 @@ import CustomFieldsForm from '../../components/CustomFieldsForm'; import { USER_STATUS_TEXT_MAX_LENGTH } from '../../components/UserStatus'; import UserStatusMenu from '../../components/UserStatusMenu'; import UserAvatarEditor from '../../components/avatar/UserAvatarEditor'; -import { useMethod } from '../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../contexts/TranslationContext'; function AccountProfileForm({ values, handlers, user, settings, onSaveStateChange, ...props }) { const t = useTranslation(); diff --git a/apps/meteor/client/views/account/AccountProfilePage.js b/apps/meteor/client/views/account/AccountProfilePage.js index 314ec215a436..81de4e9b8d53 100644 --- a/apps/meteor/client/views/account/AccountProfilePage.js +++ b/apps/meteor/client/views/account/AccountProfilePage.js @@ -1,16 +1,20 @@ import { ButtonGroup, Button, Box, Icon } from '@rocket.chat/fuselage'; +import { + useSetModal, + useToastMessageDispatch, + useUser, + useLogout, + useSetting, + useEndpoint, + useMethod, + useTranslation, +} from '@rocket.chat/ui-contexts'; import { SHA256 } from 'meteor/sha'; import React, { useMemo, useState, useCallback } from 'react'; import { getUserEmailAddress } from '../../../lib/getUserEmailAddress'; import ConfirmOwnerChangeWarningModal from '../../components/ConfirmOwnerChangeWarningModal'; import Page from '../../components/Page'; -import { useSetModal } from '../../contexts/ModalContext'; -import { useEndpoint, useMethod } from '../../contexts/ServerContext'; -import { useSetting } from '../../contexts/SettingsContext'; -import { useToastMessageDispatch } from '../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../contexts/TranslationContext'; -import { useUser, useLogout } from '../../contexts/UserContext'; import { useForm } from '../../hooks/useForm'; import { useUpdateAvatar } from '../../hooks/useUpdateAvatar'; import AccountProfileForm from './AccountProfileForm'; diff --git a/apps/meteor/client/views/account/AccountRoute.js b/apps/meteor/client/views/account/AccountRoute.js index 641c5dd45986..7daab6e21cde 100644 --- a/apps/meteor/client/views/account/AccountRoute.js +++ b/apps/meteor/client/views/account/AccountRoute.js @@ -1,9 +1,7 @@ +import { useRouteParameter, useRoute, useCurrentRoute, useSetting, usePermission } from '@rocket.chat/ui-contexts'; import React, { useEffect } from 'react'; import { SideNav } from '../../../app/ui-utils/client'; -import { usePermission } from '../../contexts/AuthorizationContext'; -import { useRouteParameter, useRoute, useCurrentRoute } from '../../contexts/RouterContext'; -import { useSetting } from '../../contexts/SettingsContext'; import NotAuthorizedPage from '../notAuthorized/NotAuthorizedPage'; import AccountIntegrationsPage from './AccountIntegrationsPage'; import AccountProfilePage from './AccountProfilePage'; diff --git a/apps/meteor/client/views/account/AccountSidebar.js b/apps/meteor/client/views/account/AccountSidebar.js index 03e5d8709fbb..dc78560b2c2f 100644 --- a/apps/meteor/client/views/account/AccountSidebar.js +++ b/apps/meteor/client/views/account/AccountSidebar.js @@ -1,10 +1,9 @@ +import { useRoutePath, useCurrentRoute, useTranslation } from '@rocket.chat/ui-contexts'; import React, { memo, useCallback, useEffect } from 'react'; import { useSubscription } from 'use-subscription'; import { menu, SideNav } from '../../../app/ui-utils/client'; import Sidebar from '../../components/Sidebar'; -import { useRoutePath, useCurrentRoute } from '../../contexts/RouterContext'; -import { useTranslation } from '../../contexts/TranslationContext'; import { isLayoutEmbedded } from '../../lib/utils/isLayoutEmbedded'; import SettingsProvider from '../../providers/SettingsProvider'; import { itemsSubscription } from './sidebarItems'; diff --git a/apps/meteor/client/views/account/ActionConfirmModal.tsx b/apps/meteor/client/views/account/ActionConfirmModal.tsx index 10a0261fd182..35b1a2208f6e 100644 --- a/apps/meteor/client/views/account/ActionConfirmModal.tsx +++ b/apps/meteor/client/views/account/ActionConfirmModal.tsx @@ -1,8 +1,8 @@ import { Box, PasswordInput, TextInput, FieldGroup, Field } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { useState, useCallback, FC } from 'react'; import GenericModal from '../../components/GenericModal'; -import { useTranslation } from '../../contexts/TranslationContext'; type ActionConfirmModalProps = { isPassword: boolean; diff --git a/apps/meteor/client/views/account/preferences/AccountPreferencesPage.js b/apps/meteor/client/views/account/preferences/AccountPreferencesPage.js index a79201ff1498..406c06695341 100644 --- a/apps/meteor/client/views/account/preferences/AccountPreferencesPage.js +++ b/apps/meteor/client/views/account/preferences/AccountPreferencesPage.js @@ -1,11 +1,8 @@ import { ButtonGroup, Button, Box, Accordion } from '@rocket.chat/fuselage'; +import { useToastMessageDispatch, useSetting, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useState, useCallback, useRef } from 'react'; import Page from '../../../components/Page'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useSetting } from '../../../contexts/SettingsContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import PreferencesGlobalSection from './PreferencesGlobalSection'; import PreferencesHighlightsSection from './PreferencesHighlightsSection'; import PreferencesLocalizationSection from './PreferencesLocalizationSection'; diff --git a/apps/meteor/client/views/account/preferences/MyDataModal.tsx b/apps/meteor/client/views/account/preferences/MyDataModal.tsx index c5f280675d51..1e05ae4f17d2 100644 --- a/apps/meteor/client/views/account/preferences/MyDataModal.tsx +++ b/apps/meteor/client/views/account/preferences/MyDataModal.tsx @@ -1,8 +1,7 @@ import { ButtonGroup, Button, Icon, Box, Modal } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; - type MyDataModalProps = { onCancel: () => void; title: string; diff --git a/apps/meteor/client/views/account/preferences/PreferencesGlobalSection.js b/apps/meteor/client/views/account/preferences/PreferencesGlobalSection.js index d5d89f83f90b..b1715e072914 100644 --- a/apps/meteor/client/views/account/preferences/PreferencesGlobalSection.js +++ b/apps/meteor/client/views/account/preferences/PreferencesGlobalSection.js @@ -1,8 +1,7 @@ import { Accordion, Field, FieldGroup, MultiSelect, ToggleSwitch, Callout } from '@rocket.chat/fuselage'; +import { useUserPreference, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useMemo } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; -import { useUserPreference } from '../../../contexts/UserContext'; import { useForm } from '../../../hooks/useForm'; const PreferencesGlobalSection = ({ onChange, commitRef, ...props }) => { diff --git a/apps/meteor/client/views/account/preferences/PreferencesHighlightsSection.js b/apps/meteor/client/views/account/preferences/PreferencesHighlightsSection.js index 09e11b3e2242..cbce6731d2a4 100644 --- a/apps/meteor/client/views/account/preferences/PreferencesHighlightsSection.js +++ b/apps/meteor/client/views/account/preferences/PreferencesHighlightsSection.js @@ -1,8 +1,7 @@ import { Accordion, Field, FieldGroup, TextAreaInput } from '@rocket.chat/fuselage'; +import { useUserPreference, useTranslation } from '@rocket.chat/ui-contexts'; import React from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; -import { useUserPreference } from '../../../contexts/UserContext'; import { useForm } from '../../../hooks/useForm'; const PreferencesHighlightsSection = ({ onChange, commitRef, ...props }) => { diff --git a/apps/meteor/client/views/account/preferences/PreferencesLocalizationSection.js b/apps/meteor/client/views/account/preferences/PreferencesLocalizationSection.js index 9fb0d12d4882..9819fe6ab97e 100644 --- a/apps/meteor/client/views/account/preferences/PreferencesLocalizationSection.js +++ b/apps/meteor/client/views/account/preferences/PreferencesLocalizationSection.js @@ -1,8 +1,7 @@ import { Accordion, Field, Select, FieldGroup } from '@rocket.chat/fuselage'; +import { useUserPreference, useLanguages, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useMemo } from 'react'; -import { useLanguages, useTranslation } from '../../../contexts/TranslationContext'; -import { useUserPreference } from '../../../contexts/UserContext'; import { useForm } from '../../../hooks/useForm'; const PreferencesLocalizationSection = ({ onChange, commitRef, ...props }) => { diff --git a/apps/meteor/client/views/account/preferences/PreferencesMessagesSection.js b/apps/meteor/client/views/account/preferences/PreferencesMessagesSection.js index bcb4aec88181..eebedb8ba77e 100644 --- a/apps/meteor/client/views/account/preferences/PreferencesMessagesSection.js +++ b/apps/meteor/client/views/account/preferences/PreferencesMessagesSection.js @@ -1,9 +1,7 @@ import { Accordion, Field, Select, FieldGroup, ToggleSwitch } from '@rocket.chat/fuselage'; +import { useUserPreference, useSetting, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useMemo } from 'react'; -import { useSetting } from '../../../contexts/SettingsContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; -import { useUserPreference } from '../../../contexts/UserContext'; import { useForm } from '../../../hooks/useForm'; const PreferencesMessagesSection = ({ onChange, commitRef, ...props }) => { diff --git a/apps/meteor/client/views/account/preferences/PreferencesMyDataSection.js b/apps/meteor/client/views/account/preferences/PreferencesMyDataSection.js index bb085fbc1c0d..f66f3e637fba 100644 --- a/apps/meteor/client/views/account/preferences/PreferencesMyDataSection.js +++ b/apps/meteor/client/views/account/preferences/PreferencesMyDataSection.js @@ -1,10 +1,7 @@ import { Accordion, Field, FieldGroup, ButtonGroup, Button, Icon, Box } from '@rocket.chat/fuselage'; +import { useSetModal, useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback } from 'react'; -import { useSetModal } from '../../../contexts/ModalContext'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import MyDataModal from './MyDataModal'; const PreferencesMyDataSection = ({ onChange, ...props }) => { diff --git a/apps/meteor/client/views/account/preferences/PreferencesNotificationsSection.js b/apps/meteor/client/views/account/preferences/PreferencesNotificationsSection.js index 8c0163636508..8a16109b6101 100644 --- a/apps/meteor/client/views/account/preferences/PreferencesNotificationsSection.js +++ b/apps/meteor/client/views/account/preferences/PreferencesNotificationsSection.js @@ -1,10 +1,8 @@ import { Accordion, Field, Select, FieldGroup, ToggleSwitch, Button, Box } from '@rocket.chat/fuselage'; +import { useUserPreference, useSetting, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback, useEffect, useState, useMemo } from 'react'; import { KonchatNotification } from '../../../../app/ui'; -import { useSetting } from '../../../contexts/SettingsContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; -import { useUserPreference } from '../../../contexts/UserContext'; import { useForm } from '../../../hooks/useForm'; const notificationOptionsLabelMap = { diff --git a/apps/meteor/client/views/account/preferences/PreferencesSoundSection.js b/apps/meteor/client/views/account/preferences/PreferencesSoundSection.js index 619b56261185..51af78255461 100644 --- a/apps/meteor/client/views/account/preferences/PreferencesSoundSection.js +++ b/apps/meteor/client/views/account/preferences/PreferencesSoundSection.js @@ -1,9 +1,8 @@ import { Accordion, Field, Select, FieldGroup, ToggleSwitch, Tooltip, Box } from '@rocket.chat/fuselage'; +import { useUserPreference, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useMemo, useCallback } from 'react'; import { CustomSounds } from '../../../../app/custom-sounds/client'; -import { useTranslation } from '../../../contexts/TranslationContext'; -import { useUserPreference } from '../../../contexts/UserContext'; import { useForm } from '../../../hooks/useForm'; const useCustomSoundsOptions = () => diff --git a/apps/meteor/client/views/account/preferences/PreferencesUserPresenceSection.js b/apps/meteor/client/views/account/preferences/PreferencesUserPresenceSection.js index f486d126758f..520850bf2b2d 100644 --- a/apps/meteor/client/views/account/preferences/PreferencesUserPresenceSection.js +++ b/apps/meteor/client/views/account/preferences/PreferencesUserPresenceSection.js @@ -1,8 +1,7 @@ import { Accordion, Field, NumberInput, FieldGroup, ToggleSwitch } from '@rocket.chat/fuselage'; +import { useUserPreference, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; -import { useUserPreference } from '../../../contexts/UserContext'; import { useForm } from '../../../hooks/useForm'; const PreferencesUserPresenceSection = ({ onChange, commitRef, ...props }) => { diff --git a/apps/meteor/client/views/account/security/AccountSecurityPage.js b/apps/meteor/client/views/account/security/AccountSecurityPage.js index 06f22448ffbc..5f0ac42860aa 100644 --- a/apps/meteor/client/views/account/security/AccountSecurityPage.js +++ b/apps/meteor/client/views/account/security/AccountSecurityPage.js @@ -1,9 +1,8 @@ import { Box, Accordion } from '@rocket.chat/fuselage'; +import { useSetting, useTranslation } from '@rocket.chat/ui-contexts'; import React from 'react'; import Page from '../../../components/Page'; -import { useSetting } from '../../../contexts/SettingsContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import NotAuthorizedPage from '../../notAuthorized/NotAuthorizedPage'; import EndToEnd from './EndToEnd'; import TwoFactorEmail from './TwoFactorEmail'; diff --git a/apps/meteor/client/views/account/security/BackupCodesModal.tsx b/apps/meteor/client/views/account/security/BackupCodesModal.tsx index 7164720cb7c0..e3a46939ed52 100644 --- a/apps/meteor/client/views/account/security/BackupCodesModal.tsx +++ b/apps/meteor/client/views/account/security/BackupCodesModal.tsx @@ -1,8 +1,8 @@ import { Box, Button, Icon, ButtonGroup, Modal } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC, useMemo } from 'react'; import TextCopy from '../../../components/TextCopy'; -import { useTranslation } from '../../../contexts/TranslationContext'; type BackupCodesModalProps = { codes: string[]; diff --git a/apps/meteor/client/views/account/security/EndToEnd.js b/apps/meteor/client/views/account/security/EndToEnd.js index 367f3f1c823d..5c8c381d520b 100644 --- a/apps/meteor/client/views/account/security/EndToEnd.js +++ b/apps/meteor/client/views/account/security/EndToEnd.js @@ -1,15 +1,11 @@ import { Box, Margins, PasswordInput, Field, FieldGroup, Button } from '@rocket.chat/fuselage'; import { useLocalStorage, useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useToastMessageDispatch, useRoute, useUser, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; import React, { useCallback, useEffect } from 'react'; import { e2e } from '../../../../app/e2e/client/rocketchat.e2e'; import { callbacks } from '../../../../lib/callbacks'; -import { useRoute } from '../../../contexts/RouterContext'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; -import { useUser } from '../../../contexts/UserContext'; import { useForm } from '../../../hooks/useForm'; const EndToEnd = (props) => { diff --git a/apps/meteor/client/views/account/security/TwoFactorEmail.js b/apps/meteor/client/views/account/security/TwoFactorEmail.js index 13fdcebe2a85..767b5afcdae2 100644 --- a/apps/meteor/client/views/account/security/TwoFactorEmail.js +++ b/apps/meteor/client/views/account/security/TwoFactorEmail.js @@ -1,8 +1,7 @@ import { Box, Button, Margins } from '@rocket.chat/fuselage'; +import { useUser, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; -import { useUser } from '../../../contexts/UserContext'; import { useEndpointAction } from '../../../hooks/useEndpointAction'; const TwoFactorEmail = (props) => { diff --git a/apps/meteor/client/views/account/security/TwoFactorTOTP.js b/apps/meteor/client/views/account/security/TwoFactorTOTP.js index 5ba796588e9a..1b17170ccaed 100644 --- a/apps/meteor/client/views/account/security/TwoFactorTOTP.js +++ b/apps/meteor/client/views/account/security/TwoFactorTOTP.js @@ -1,15 +1,11 @@ import { Box, Button, TextInput, Margins } from '@rocket.chat/fuselage'; import { useSafely } from '@rocket.chat/fuselage-hooks'; +import { useSetModal, useToastMessageDispatch, useUser, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useState, useCallback, useEffect } from 'react'; import qrcode from 'yaqrcode'; import TextCopy from '../../../components/TextCopy'; import TwoFactorTotpModal from '../../../components/TwoFactorModal/TwoFactorTotpModal'; -import { useSetModal } from '../../../contexts/ModalContext'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; -import { useUser } from '../../../contexts/UserContext'; import { useForm } from '../../../hooks/useForm'; import BackupCodesModal from './BackupCodesModal'; diff --git a/apps/meteor/client/views/account/tokens/AccountTokensPage.js b/apps/meteor/client/views/account/tokens/AccountTokensPage.js index 61df855c1699..ba7a939753d4 100644 --- a/apps/meteor/client/views/account/tokens/AccountTokensPage.js +++ b/apps/meteor/client/views/account/tokens/AccountTokensPage.js @@ -1,7 +1,7 @@ +import { useTranslation } from '@rocket.chat/ui-contexts'; import React from 'react'; import Page from '../../../components/Page'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useEndpointData } from '../../../hooks/useEndpointData'; import AccountTokensTable from './AccountTokensTable'; import AddToken from './AddToken'; diff --git a/apps/meteor/client/views/account/tokens/AccountTokensRow.tsx b/apps/meteor/client/views/account/tokens/AccountTokensRow.tsx index 7f6f93bd0c25..188ca546ed7e 100644 --- a/apps/meteor/client/views/account/tokens/AccountTokensRow.tsx +++ b/apps/meteor/client/views/account/tokens/AccountTokensRow.tsx @@ -1,8 +1,8 @@ import { Button, ButtonGroup, Icon, Table } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import type { MomentInput } from 'moment'; import React, { useCallback, FC } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useFormatDateAndTime } from '../../../hooks/useFormatDateAndTime'; type AccountTokensRowProps = { diff --git a/apps/meteor/client/views/account/tokens/AccountTokensTable.js b/apps/meteor/client/views/account/tokens/AccountTokensTable.js index 82200377dfd8..70fb7f80aad6 100644 --- a/apps/meteor/client/views/account/tokens/AccountTokensTable.js +++ b/apps/meteor/client/views/account/tokens/AccountTokensTable.js @@ -1,12 +1,8 @@ import { Box } from '@rocket.chat/fuselage'; +import { useSetModal, useToastMessageDispatch, useUserId, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useMemo, useCallback, useState } from 'react'; import GenericTable from '../../../components/GenericTable'; -import { useSetModal } from '../../../contexts/ModalContext'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; -import { useUserId } from '../../../contexts/UserContext'; import { useResizeInlineBreakpoint } from '../../../hooks/useResizeInlineBreakpoint'; import AccountTokensRow from './AccountTokensRow'; import InfoModal from './InfoModal'; diff --git a/apps/meteor/client/views/account/tokens/AddToken.js b/apps/meteor/client/views/account/tokens/AddToken.js index e4f0689fe35f..dbcdbcae0a0f 100644 --- a/apps/meteor/client/views/account/tokens/AddToken.js +++ b/apps/meteor/client/views/account/tokens/AddToken.js @@ -1,12 +1,8 @@ import { Box, TextInput, Button, Field, FieldGroup, Margins, CheckBox } from '@rocket.chat/fuselage'; import { useUniqueId } from '@rocket.chat/fuselage-hooks'; +import { useSetModal, useToastMessageDispatch, useUserId, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback } from 'react'; -import { useSetModal } from '../../../contexts/ModalContext'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; -import { useUserId } from '../../../contexts/UserContext'; import { useForm } from '../../../hooks/useForm'; import InfoModal from './InfoModal'; diff --git a/apps/meteor/client/views/admin/AdministrationRouter.tsx b/apps/meteor/client/views/admin/AdministrationRouter.tsx index 132704acc81a..6a9095a83617 100644 --- a/apps/meteor/client/views/admin/AdministrationRouter.tsx +++ b/apps/meteor/client/views/admin/AdministrationRouter.tsx @@ -1,7 +1,7 @@ +import { useCurrentRoute, useRoute } from '@rocket.chat/ui-contexts'; import React, { Suspense, ReactElement, useEffect } from 'react'; import PageSkeleton from '../../components/PageSkeleton'; -import { useCurrentRoute, useRoute } from '../../contexts/RouterContext'; import SettingsProvider from '../../providers/SettingsProvider'; import { useUpgradeTabParams } from '../hooks/useUpgradeTabParams'; import AdministrationLayout from './AdministrationLayout'; diff --git a/apps/meteor/client/contexts/EditableSettingsContext.ts b/apps/meteor/client/views/admin/EditableSettingsContext.ts similarity index 97% rename from apps/meteor/client/contexts/EditableSettingsContext.ts rename to apps/meteor/client/views/admin/EditableSettingsContext.ts index 66ade8b1baf6..af21e8d7f4d4 100644 --- a/apps/meteor/client/contexts/EditableSettingsContext.ts +++ b/apps/meteor/client/views/admin/EditableSettingsContext.ts @@ -1,9 +1,8 @@ import { ISettingBase, SectionName, SettingId, GroupId, TabId } from '@rocket.chat/core-typings'; +import { SettingsContextQuery } from '@rocket.chat/ui-contexts'; import { createContext, useContext, useMemo } from 'react'; import { useSubscription, Subscription, Unsubscribe } from 'use-subscription'; -import { SettingsContextQuery } from './SettingsContext'; - export interface IEditableSetting extends ISettingBase { disabled: boolean; changed: boolean; diff --git a/apps/meteor/client/views/admin/apps/APIsDisplay.tsx b/apps/meteor/client/views/admin/apps/APIsDisplay.tsx index ed8f5506a098..11869cd5fa7f 100644 --- a/apps/meteor/client/views/admin/apps/APIsDisplay.tsx +++ b/apps/meteor/client/views/admin/apps/APIsDisplay.tsx @@ -1,9 +1,8 @@ import { IApiEndpointMetadata } from '@rocket.chat/apps-engine/definition/api'; import { Box, Divider } from '@rocket.chat/fuselage'; +import { useAbsoluteUrl, useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC, Fragment } from 'react'; -import { useAbsoluteUrl } from '../../../contexts/ServerContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { apiCurlGetter } from './helpers'; type APIsDisplayProps = { diff --git a/apps/meteor/client/views/admin/apps/AppDetailsPage.tsx b/apps/meteor/client/views/admin/apps/AppDetailsPage.tsx index 3ae2daf98c0e..920efb1373c4 100644 --- a/apps/meteor/client/views/admin/apps/AppDetailsPage.tsx +++ b/apps/meteor/client/views/admin/apps/AppDetailsPage.tsx @@ -1,11 +1,10 @@ import { ISetting } from '@rocket.chat/apps-engine/definition/settings'; import { Button, ButtonGroup, Icon, Box, Throbber } from '@rocket.chat/fuselage'; +import { useRoute, useCurrentRoute, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useState, useCallback, useRef, FC } from 'react'; import { Apps } from '../../../../app/apps/client/orchestrator'; import Page from '../../../components/Page'; -import { useRoute, useCurrentRoute } from '../../../contexts/RouterContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import APIsDisplay from './APIsDisplay'; import AppDetailsPageContent from './AppDetailsPageContent'; import LoadingDetails from './LoadingDetails'; diff --git a/apps/meteor/client/views/admin/apps/AppDetailsPageContent.tsx b/apps/meteor/client/views/admin/apps/AppDetailsPageContent.tsx index 3c97bfdbcce7..3288a0904586 100644 --- a/apps/meteor/client/views/admin/apps/AppDetailsPageContent.tsx +++ b/apps/meteor/client/views/admin/apps/AppDetailsPageContent.tsx @@ -1,10 +1,10 @@ /* eslint-disable @typescript-eslint/no-use-before-define */ import { Box, Callout, Chip, Divider, Margins } from '@rocket.chat/fuselage'; +import { TranslationKey, useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; import ExternalLink from '../../../components/ExternalLink'; import AppAvatar from '../../../components/avatar/AppAvatar'; -import { TranslationKey, useTranslation } from '../../../contexts/TranslationContext'; import AppMenu from './AppMenu'; import AppStatus from './AppStatus'; import PriceDisplay from './PriceDisplay'; diff --git a/apps/meteor/client/views/admin/apps/AppInstallPage.js b/apps/meteor/client/views/admin/apps/AppInstallPage.js index 0a6d4168ab7e..24ff2b6dae09 100644 --- a/apps/meteor/client/views/admin/apps/AppInstallPage.js +++ b/apps/meteor/client/views/admin/apps/AppInstallPage.js @@ -1,12 +1,9 @@ import { Button, ButtonGroup, Icon, Field, FieldGroup, TextInput, Throbber } from '@rocket.chat/fuselage'; +import { useSetModal, useRoute, useQueryStringParameter, useEndpoint, useUpload, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback, useEffect, useState } from 'react'; import { Apps } from '../../../../app/apps/client/orchestrator'; import Page from '../../../components/Page'; -import { useSetModal } from '../../../contexts/ModalContext'; -import { useRoute, useQueryStringParameter } from '../../../contexts/RouterContext'; -import { useEndpoint, useUpload } from '../../../contexts/ServerContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useFileInput } from '../../../hooks/useFileInput'; import { useForm } from '../../../hooks/useForm'; import AppPermissionsReviewModal from './AppPermissionsReviewModal'; diff --git a/apps/meteor/client/views/admin/apps/AppLogsPage.js b/apps/meteor/client/views/admin/apps/AppLogsPage.js index 17f0d3f604cb..5d754de2aa30 100644 --- a/apps/meteor/client/views/admin/apps/AppLogsPage.js +++ b/apps/meteor/client/views/admin/apps/AppLogsPage.js @@ -1,11 +1,9 @@ import { Box, Button, ButtonGroup, Icon, Accordion, Pagination } from '@rocket.chat/fuselage'; import { useSafely } from '@rocket.chat/fuselage-hooks'; +import { useCurrentRoute, useRoute, useEndpoint, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback, useState, useEffect } from 'react'; import Page from '../../../components/Page'; -import { useCurrentRoute, useRoute } from '../../../contexts/RouterContext'; -import { useEndpoint } from '../../../contexts/ServerContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useFormatDateAndTime } from '../../../hooks/useFormatDateAndTime'; import LogItem from './LogItem'; import LogsLoading from './LogsLoading'; diff --git a/apps/meteor/client/views/admin/apps/AppMenu.js b/apps/meteor/client/views/admin/apps/AppMenu.js index 1a5d87a6b342..1352d4dc2d9f 100644 --- a/apps/meteor/client/views/admin/apps/AppMenu.js +++ b/apps/meteor/client/views/admin/apps/AppMenu.js @@ -1,10 +1,7 @@ import { Box, Icon, Menu } from '@rocket.chat/fuselage'; +import { useSetModal, useRoute, useMethod, useEndpoint, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useMemo, useCallback } from 'react'; -import { useSetModal } from '../../../contexts/ModalContext'; -import { useRoute } from '../../../contexts/RouterContext'; -import { useMethod, useEndpoint } from '../../../contexts/ServerContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import CloudLoginModal from './CloudLoginModal'; import IframeModal from './IframeModal'; import WarningModal from './WarningModal'; diff --git a/apps/meteor/client/views/admin/apps/AppPermissionsReviewModal.js b/apps/meteor/client/views/admin/apps/AppPermissionsReviewModal.js index 4185c0f993be..82f4e74c4d4c 100644 --- a/apps/meteor/client/views/admin/apps/AppPermissionsReviewModal.js +++ b/apps/meteor/client/views/admin/apps/AppPermissionsReviewModal.js @@ -1,8 +1,7 @@ import { Button, ButtonGroup, Icon, Modal } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; - const AppPermissionsReviewModal = ({ appPermissions, cancel, confirm, modalProps = {} }) => { const t = useTranslation(); diff --git a/apps/meteor/client/views/admin/apps/AppRow.tsx b/apps/meteor/client/views/admin/apps/AppRow.tsx index 23d988aab82d..b03fb6569a05 100644 --- a/apps/meteor/client/views/admin/apps/AppRow.tsx +++ b/apps/meteor/client/views/admin/apps/AppRow.tsx @@ -1,9 +1,8 @@ import { Box, Table, Tag } from '@rocket.chat/fuselage'; +import { useRoute, useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC, useState, memo, KeyboardEvent, MouseEvent } from 'react'; import AppAvatar from '../../../components/avatar/AppAvatar'; -import { useRoute } from '../../../contexts/RouterContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import AppMenu from './AppMenu'; import AppStatus from './AppStatus'; import { App } from './types'; diff --git a/apps/meteor/client/views/admin/apps/AppSetting.js b/apps/meteor/client/views/admin/apps/AppSetting.js index 1dfd4f824a58..27d144c14817 100644 --- a/apps/meteor/client/views/admin/apps/AppSetting.js +++ b/apps/meteor/client/views/admin/apps/AppSetting.js @@ -1,8 +1,7 @@ +import { useRouteParameter, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useMemo, useCallback } from 'react'; import MarkdownText from '../../../components/MarkdownText'; -import { useRouteParameter } from '../../../contexts/RouterContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import MemoizedSetting from '../settings/MemoizedSetting'; const useAppTranslation = (appId) => { diff --git a/apps/meteor/client/views/admin/apps/AppStatus.js b/apps/meteor/client/views/admin/apps/AppStatus.js index e99da2654191..179b7d23aa63 100644 --- a/apps/meteor/client/views/admin/apps/AppStatus.js +++ b/apps/meteor/client/views/admin/apps/AppStatus.js @@ -1,11 +1,9 @@ import { Box, Button, Icon, Throbber } from '@rocket.chat/fuselage'; import { useSafely } from '@rocket.chat/fuselage-hooks'; +import { useSetModal, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback, useState, memo } from 'react'; import { Apps } from '../../../../app/apps/client/orchestrator'; -import { useSetModal } from '../../../contexts/ModalContext'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import AppPermissionsReviewModal from './AppPermissionsReviewModal'; import CloudLoginModal from './CloudLoginModal'; import IframeModal from './IframeModal'; diff --git a/apps/meteor/client/views/admin/apps/AppUpdateModal.tsx b/apps/meteor/client/views/admin/apps/AppUpdateModal.tsx index 72c3efa6bf26..e8ebb15c2dc7 100644 --- a/apps/meteor/client/views/admin/apps/AppUpdateModal.tsx +++ b/apps/meteor/client/views/admin/apps/AppUpdateModal.tsx @@ -1,8 +1,7 @@ import { Button, ButtonGroup, Icon, Modal } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; - type AppUpdateModalProps = { confirm: () => void; cancel: () => void; diff --git a/apps/meteor/client/views/admin/apps/AppsPage.tsx b/apps/meteor/client/views/admin/apps/AppsPage.tsx index 578217c79851..44542bee035c 100644 --- a/apps/meteor/client/views/admin/apps/AppsPage.tsx +++ b/apps/meteor/client/views/admin/apps/AppsPage.tsx @@ -1,11 +1,8 @@ import { Button, ButtonGroup, Icon, Skeleton, Tabs } from '@rocket.chat/fuselage'; +import { useRoute, useSetting, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useEffect, useState, ReactElement } from 'react'; import Page from '../../../components/Page'; -import { useRoute } from '../../../contexts/RouterContext'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useSetting } from '../../../contexts/SettingsContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import AppsTable from './AppsTable'; type AppsPageProps = { diff --git a/apps/meteor/client/views/admin/apps/AppsRoute.tsx b/apps/meteor/client/views/admin/apps/AppsRoute.tsx index 53a41f68df75..907394388c2e 100644 --- a/apps/meteor/client/views/admin/apps/AppsRoute.tsx +++ b/apps/meteor/client/views/admin/apps/AppsRoute.tsx @@ -1,9 +1,7 @@ +import { useRouteParameter, useRoute, usePermission, useMethod } from '@rocket.chat/ui-contexts'; import React, { useState, useEffect, FC } from 'react'; import PageSkeleton from '../../../components/PageSkeleton'; -import { usePermission } from '../../../contexts/AuthorizationContext'; -import { useRouteParameter, useRoute } from '../../../contexts/RouterContext'; -import { useMethod } from '../../../contexts/ServerContext'; import NotAuthorizedPage from '../../notAuthorized/NotAuthorizedPage'; import AppDetailsPage from './AppDetailsPage'; import AppInstallPage from './AppInstallPage'; diff --git a/apps/meteor/client/views/admin/apps/AppsTable.tsx b/apps/meteor/client/views/admin/apps/AppsTable.tsx index dc426fe6c88f..b4d157856a00 100644 --- a/apps/meteor/client/views/admin/apps/AppsTable.tsx +++ b/apps/meteor/client/views/admin/apps/AppsTable.tsx @@ -14,6 +14,7 @@ import { Icon, } from '@rocket.chat/fuselage'; import { useDebouncedState } from '@rocket.chat/fuselage-hooks'; +import { useRoute, useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC, useMemo, useState } from 'react'; import FilterByText from '../../../components/FilterByText'; @@ -25,8 +26,6 @@ import { GenericTableLoadingTable, } from '../../../components/GenericTable'; import { usePagination } from '../../../components/GenericTable/hooks/usePagination'; -import { useRoute } from '../../../contexts/RouterContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useResizeInlineBreakpoint } from '../../../hooks/useResizeInlineBreakpoint'; import { AsyncStatePhase } from '../../../lib/asyncState'; import AppRow from './AppRow'; diff --git a/apps/meteor/client/views/admin/apps/AppsWhatIsIt.tsx b/apps/meteor/client/views/admin/apps/AppsWhatIsIt.tsx index 5e1a50efd76f..8cecdcf6cb90 100644 --- a/apps/meteor/client/views/admin/apps/AppsWhatIsIt.tsx +++ b/apps/meteor/client/views/admin/apps/AppsWhatIsIt.tsx @@ -1,12 +1,10 @@ import { Button, Box, Throbber } from '@rocket.chat/fuselage'; +import { useRoute, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC, useState } from 'react'; import { Apps } from '../../../../app/apps/client'; import ExternalLink from '../../../components/ExternalLink'; import Page from '../../../components/Page'; -import { useRoute } from '../../../contexts/RouterContext'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; const readMeUrl = 'https://go.rocket.chat/i/developing-an-app'; diff --git a/apps/meteor/client/views/admin/apps/CloudLoginModal.tsx b/apps/meteor/client/views/admin/apps/CloudLoginModal.tsx index 35a069e3a82d..bf788bc2060d 100644 --- a/apps/meteor/client/views/admin/apps/CloudLoginModal.tsx +++ b/apps/meteor/client/views/admin/apps/CloudLoginModal.tsx @@ -1,9 +1,7 @@ +import { useSetModal, useRoute, useTranslation } from '@rocket.chat/ui-contexts'; import React, { ReactElement } from 'react'; import GenericModal from '../../../components/GenericModal'; -import { useSetModal } from '../../../contexts/ModalContext'; -import { useRoute } from '../../../contexts/RouterContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; const CloudLoginModal = (): ReactElement => { const t = useTranslation(); diff --git a/apps/meteor/client/views/admin/apps/LogEntry.tsx b/apps/meteor/client/views/admin/apps/LogEntry.tsx index 58111c0e803d..80db19ffa8f5 100644 --- a/apps/meteor/client/views/admin/apps/LogEntry.tsx +++ b/apps/meteor/client/views/admin/apps/LogEntry.tsx @@ -1,7 +1,7 @@ import { Box } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useHighlightedCode } from '../../../hooks/useHighlightedCode'; type LogEntryProps = { diff --git a/apps/meteor/client/views/admin/apps/LogItem.tsx b/apps/meteor/client/views/admin/apps/LogItem.tsx index e386bc5a9449..dccf796cb401 100644 --- a/apps/meteor/client/views/admin/apps/LogItem.tsx +++ b/apps/meteor/client/views/admin/apps/LogItem.tsx @@ -1,7 +1,7 @@ import { Box, Accordion } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; import LogEntry from './LogEntry'; type LogItemProps = { diff --git a/apps/meteor/client/views/admin/apps/MarketplaceRow.tsx b/apps/meteor/client/views/admin/apps/MarketplaceRow.tsx index a8f0eeaa731f..8c63ed3b7cb7 100644 --- a/apps/meteor/client/views/admin/apps/MarketplaceRow.tsx +++ b/apps/meteor/client/views/admin/apps/MarketplaceRow.tsx @@ -1,9 +1,8 @@ import { Box, Table, Tag } from '@rocket.chat/fuselage'; +import { useRoute, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useState, memo, FC, KeyboardEvent, MouseEvent } from 'react'; import AppAvatar from '../../../components/avatar/AppAvatar'; -import { useRoute } from '../../../contexts/RouterContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import AppMenu from './AppMenu'; import AppStatus from './AppStatus'; import PriceDisplay from './PriceDisplay'; diff --git a/apps/meteor/client/views/admin/apps/PriceDisplay.js b/apps/meteor/client/views/admin/apps/PriceDisplay.js index c2f7b1ecc541..cfdfc956e914 100644 --- a/apps/meteor/client/views/admin/apps/PriceDisplay.js +++ b/apps/meteor/client/views/admin/apps/PriceDisplay.js @@ -1,7 +1,7 @@ import { Box } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { useMemo } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { formatPricingPlan, formatPrice } from './helpers'; const formatPriceAndPurchaseType = (purchaseType, pricingPlans, price) => { diff --git a/apps/meteor/client/views/admin/apps/SettingsDisplay.tsx b/apps/meteor/client/views/admin/apps/SettingsDisplay.tsx index e0612aad6f7e..3556e8d44f58 100644 --- a/apps/meteor/client/views/admin/apps/SettingsDisplay.tsx +++ b/apps/meteor/client/views/admin/apps/SettingsDisplay.tsx @@ -1,8 +1,8 @@ import { ISetting } from '@rocket.chat/apps-engine/definition/settings'; import { Box, Divider } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC, useMemo, useEffect, MutableRefObject } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useForm } from '../../../hooks/useForm'; import AppSettingsAssembler from './AppSettingsAssembler'; diff --git a/apps/meteor/client/views/admin/apps/WarningModal.js b/apps/meteor/client/views/admin/apps/WarningModal.js index f40a69c973a6..982d743dd73c 100644 --- a/apps/meteor/client/views/admin/apps/WarningModal.js +++ b/apps/meteor/client/views/admin/apps/WarningModal.js @@ -1,8 +1,7 @@ import { Button, ButtonGroup, Icon, Modal } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; - const WarningModal = ({ text, confirmText, close, cancel, cancelText, confirm, ...props }) => { const t = useTranslation(); return ( diff --git a/apps/meteor/client/views/admin/apps/components/CategoryFilter/CategoryDropDownAnchor.tsx b/apps/meteor/client/views/admin/apps/components/CategoryFilter/CategoryDropDownAnchor.tsx index fdf9ec9169f0..e91bfae07682 100644 --- a/apps/meteor/client/views/admin/apps/components/CategoryFilter/CategoryDropDownAnchor.tsx +++ b/apps/meteor/client/views/admin/apps/components/CategoryFilter/CategoryDropDownAnchor.tsx @@ -1,8 +1,7 @@ import { Box, Button, Icon, Select } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { ComponentProps, forwardRef } from 'react'; -import { useTranslation } from '../../../../../contexts/TranslationContext'; - const CategoryDropDownAnchor = forwardRef> & { selectedCategoriesCount: number }>( function CategoryDropDownAnchor(props, ref) { const t = useTranslation(); diff --git a/apps/meteor/client/views/admin/apps/hooks/useCategories.ts b/apps/meteor/client/views/admin/apps/hooks/useCategories.ts index d7f7d349310b..172d7facebe4 100644 --- a/apps/meteor/client/views/admin/apps/hooks/useCategories.ts +++ b/apps/meteor/client/views/admin/apps/hooks/useCategories.ts @@ -1,7 +1,7 @@ +import { useTranslation } from '@rocket.chat/ui-contexts'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { Apps } from '../../../../../app/apps/client/orchestrator'; -import { useTranslation } from '../../../../contexts/TranslationContext'; import { CategoryDropdownItem, CategoryDropDownListProps } from '../definitions/CategoryDropdownDefinitions'; import { handleAPIError } from '../helpers'; import { useCategoryFlatList } from './useCategoryFlatList'; diff --git a/apps/meteor/client/views/admin/cloud/CloudPage.tsx b/apps/meteor/client/views/admin/cloud/CloudPage.tsx index b99b8a87917f..c12c109705c9 100644 --- a/apps/meteor/client/views/admin/cloud/CloudPage.tsx +++ b/apps/meteor/client/views/admin/cloud/CloudPage.tsx @@ -1,12 +1,16 @@ import { Box, Button, ButtonGroup, Margins } from '@rocket.chat/fuselage'; +import { + useSetModal, + useToastMessageDispatch, + useQueryStringParameter, + useRoute, + useRouteParameter, + useMethod, + useTranslation, +} from '@rocket.chat/ui-contexts'; import React, { useEffect, ReactNode } from 'react'; import Page from '../../../components/Page'; -import { useSetModal } from '../../../contexts/ModalContext'; -import { useQueryStringParameter, useRoute, useRouteParameter } from '../../../contexts/RouterContext'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useMethodData } from '../../../hooks/useMethodData'; import ConnectToCloudSection from './ConnectToCloudSection'; import ManualWorkspaceRegistrationModal from './ManualWorkspaceRegistrationModal'; diff --git a/apps/meteor/client/views/admin/cloud/CloudRoute.js b/apps/meteor/client/views/admin/cloud/CloudRoute.js index 5a469c8fc316..4fb12961d043 100644 --- a/apps/meteor/client/views/admin/cloud/CloudRoute.js +++ b/apps/meteor/client/views/admin/cloud/CloudRoute.js @@ -1,6 +1,6 @@ +import { usePermission } from '@rocket.chat/ui-contexts'; import React from 'react'; -import { usePermission } from '../../../contexts/AuthorizationContext'; import NotAuthorizedPage from '../../notAuthorized/NotAuthorizedPage'; import CloudPage from './CloudPage'; diff --git a/apps/meteor/client/views/admin/cloud/ConnectToCloudSection.js b/apps/meteor/client/views/admin/cloud/ConnectToCloudSection.js index cfdb2f6c6b56..94676b0ebfc8 100644 --- a/apps/meteor/client/views/admin/cloud/ConnectToCloudSection.js +++ b/apps/meteor/client/views/admin/cloud/ConnectToCloudSection.js @@ -1,12 +1,9 @@ import { Box, Button, ButtonGroup, Throbber, Callout } from '@rocket.chat/fuselage'; import { useSafely } from '@rocket.chat/fuselage-hooks'; +import { useToastMessageDispatch, useSetting, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useState } from 'react'; import Subtitle from '../../../components/Subtitle'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useSetting } from '../../../contexts/SettingsContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; function ConnectToCloudSection({ onRegisterStatusChange, ...props }) { const t = useTranslation(); diff --git a/apps/meteor/client/views/admin/cloud/CopyStep.tsx b/apps/meteor/client/views/admin/cloud/CopyStep.tsx index acd3a675283f..b69c5cae74b8 100644 --- a/apps/meteor/client/views/admin/cloud/CopyStep.tsx +++ b/apps/meteor/client/views/admin/cloud/CopyStep.tsx @@ -1,11 +1,9 @@ import { Box, Button, ButtonGroup, Icon, Scrollable, Modal } from '@rocket.chat/fuselage'; +import { useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import Clipboard from 'clipboard'; import React, { useEffect, useState, useRef, FC } from 'react'; import MarkdownText from '../../../components/MarkdownText'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { cloudConsoleUrl } from './constants'; type CopyStepProps = { diff --git a/apps/meteor/client/views/admin/cloud/ManualWorkspaceRegistrationModal.js b/apps/meteor/client/views/admin/cloud/ManualWorkspaceRegistrationModal.js index 2a71c71f387e..8b8c8d4bc6aa 100644 --- a/apps/meteor/client/views/admin/cloud/ManualWorkspaceRegistrationModal.js +++ b/apps/meteor/client/views/admin/cloud/ManualWorkspaceRegistrationModal.js @@ -1,7 +1,7 @@ import { Modal } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { useState } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; import CopyStep from './CopyStep'; import PasteStep from './PasteStep'; diff --git a/apps/meteor/client/views/admin/cloud/PasteStep.tsx b/apps/meteor/client/views/admin/cloud/PasteStep.tsx index 1da05d5bbe12..254882680d32 100644 --- a/apps/meteor/client/views/admin/cloud/PasteStep.tsx +++ b/apps/meteor/client/views/admin/cloud/PasteStep.tsx @@ -1,10 +1,7 @@ import { Box, Button, ButtonGroup, Scrollable, Throbber, Modal } from '@rocket.chat/fuselage'; +import { useToastMessageDispatch, useEndpoint, useTranslation } from '@rocket.chat/ui-contexts'; import React, { ChangeEvent, FC, useState } from 'react'; -import { useEndpoint } from '../../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; - type PasteStepProps = { onBackButtonClick: () => void; onFinish: () => void; diff --git a/apps/meteor/client/views/admin/cloud/TroubleshootingSection.js b/apps/meteor/client/views/admin/cloud/TroubleshootingSection.js index 49798444d617..6ce3bf252d81 100644 --- a/apps/meteor/client/views/admin/cloud/TroubleshootingSection.js +++ b/apps/meteor/client/views/admin/cloud/TroubleshootingSection.js @@ -1,11 +1,9 @@ import { Box, Button, ButtonGroup, Throbber } from '@rocket.chat/fuselage'; import { useSafely } from '@rocket.chat/fuselage-hooks'; +import { useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useState } from 'react'; import Subtitle from '../../../components/Subtitle'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { statusPageUrl } from './constants'; function TroubleshootingSection({ onRegisterStatusChange, ...props }) { diff --git a/apps/meteor/client/views/admin/cloud/WhatIsItSection.js b/apps/meteor/client/views/admin/cloud/WhatIsItSection.js index bb601fc8c0db..c9792bef40af 100644 --- a/apps/meteor/client/views/admin/cloud/WhatIsItSection.js +++ b/apps/meteor/client/views/admin/cloud/WhatIsItSection.js @@ -1,8 +1,8 @@ import { Box } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React from 'react'; import Subtitle from '../../../components/Subtitle'; -import { useTranslation } from '../../../contexts/TranslationContext'; function WhatIsItSection(props) { const t = useTranslation(); diff --git a/apps/meteor/client/views/admin/cloud/WorkspaceLoginSection.js b/apps/meteor/client/views/admin/cloud/WorkspaceLoginSection.js index e3a67a579a4d..8a2cbdd7f666 100644 --- a/apps/meteor/client/views/admin/cloud/WorkspaceLoginSection.js +++ b/apps/meteor/client/views/admin/cloud/WorkspaceLoginSection.js @@ -1,11 +1,8 @@ import { Box, Button, ButtonGroup } from '@rocket.chat/fuselage'; import { useSafely } from '@rocket.chat/fuselage-hooks'; +import { useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useState, useEffect } from 'react'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; - function WorkspaceLoginSection({ onRegisterStatusChange, ...props }) { const t = useTranslation(); const dispatchToastMessage = useToastMessageDispatch(); diff --git a/apps/meteor/client/views/admin/cloud/WorkspaceRegistrationSection.js b/apps/meteor/client/views/admin/cloud/WorkspaceRegistrationSection.js index e2ab0e51e61b..c883df3371d7 100644 --- a/apps/meteor/client/views/admin/cloud/WorkspaceRegistrationSection.js +++ b/apps/meteor/client/views/admin/cloud/WorkspaceRegistrationSection.js @@ -1,11 +1,8 @@ import { Box, Button, ButtonGroup, Field, Margins, TextInput } from '@rocket.chat/fuselage'; import { useSafely, useUniqueId } from '@rocket.chat/fuselage-hooks'; +import { useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useState } from 'react'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; - function WorkspaceRegistrationSection({ token: initialToken, workspaceId, uniqueId, onRegisterStatusChange, ...props }) { const t = useTranslation(); const dispatchToastMessage = useToastMessageDispatch(); diff --git a/apps/meteor/client/views/admin/customEmoji/AddCustomEmoji.tsx b/apps/meteor/client/views/admin/customEmoji/AddCustomEmoji.tsx index a8c9a4751734..6566c69c2243 100644 --- a/apps/meteor/client/views/admin/customEmoji/AddCustomEmoji.tsx +++ b/apps/meteor/client/views/admin/customEmoji/AddCustomEmoji.tsx @@ -1,8 +1,8 @@ import { Box, Button, ButtonGroup, Margins, TextInput, Field, Icon } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback, useState, ReactElement, ChangeEvent } from 'react'; import VerticalBar from '../../../components/VerticalBar'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useEndpointUpload } from '../../../hooks/useEndpointUpload'; import { useFileInput } from '../../../hooks/useFileInput'; diff --git a/apps/meteor/client/views/admin/customEmoji/CustomEmoji.tsx b/apps/meteor/client/views/admin/customEmoji/CustomEmoji.tsx index a6761be3be00..2bccdf19ba1c 100644 --- a/apps/meteor/client/views/admin/customEmoji/CustomEmoji.tsx +++ b/apps/meteor/client/views/admin/customEmoji/CustomEmoji.tsx @@ -1,5 +1,6 @@ import { Box, Pagination } from '@rocket.chat/fuselage'; import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { FC, MutableRefObject, useEffect, useMemo, useState } from 'react'; import FilterByText from '../../../components/FilterByText'; @@ -14,7 +15,6 @@ import { } from '../../../components/GenericTable'; import { usePagination } from '../../../components/GenericTable/hooks/usePagination'; import { useSort } from '../../../components/GenericTable/hooks/useSort'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useEndpointData } from '../../../hooks/useEndpointData'; import { AsyncStatePhase } from '../../../lib/asyncState'; diff --git a/apps/meteor/client/views/admin/customEmoji/CustomEmojiRoute.tsx b/apps/meteor/client/views/admin/customEmoji/CustomEmojiRoute.tsx index 6ea6319c11a8..84de4c8ac119 100644 --- a/apps/meteor/client/views/admin/customEmoji/CustomEmojiRoute.tsx +++ b/apps/meteor/client/views/admin/customEmoji/CustomEmojiRoute.tsx @@ -1,11 +1,9 @@ import { Button, Icon } from '@rocket.chat/fuselage'; +import { useRoute, useRouteParameter, usePermission, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback, useRef, ReactElement } from 'react'; import Page from '../../../components/Page'; import VerticalBar from '../../../components/VerticalBar'; -import { usePermission } from '../../../contexts/AuthorizationContext'; -import { useRoute, useRouteParameter } from '../../../contexts/RouterContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import NotAuthorizedPage from '../../notAuthorized/NotAuthorizedPage'; import AddCustomEmoji from './AddCustomEmoji'; import CustomEmoji from './CustomEmoji'; diff --git a/apps/meteor/client/views/admin/customEmoji/EditCustomEmoji.tsx b/apps/meteor/client/views/admin/customEmoji/EditCustomEmoji.tsx index f111066d4043..61472d809323 100644 --- a/apps/meteor/client/views/admin/customEmoji/EditCustomEmoji.tsx +++ b/apps/meteor/client/views/admin/customEmoji/EditCustomEmoji.tsx @@ -1,12 +1,9 @@ import { Box, Button, ButtonGroup, Margins, TextInput, Field, Icon, FieldGroup } from '@rocket.chat/fuselage'; +import { useSetModal, useToastMessageDispatch, useAbsoluteUrl, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback, useState, useMemo, useEffect, FC, ChangeEvent } from 'react'; import GenericModal from '../../../components/GenericModal'; import VerticalBar from '../../../components/VerticalBar'; -import { useSetModal } from '../../../contexts/ModalContext'; -import { useAbsoluteUrl } from '../../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useEndpointAction } from '../../../hooks/useEndpointAction'; import { useEndpointUpload } from '../../../hooks/useEndpointUpload'; import { useFileInput } from '../../../hooks/useFileInput'; diff --git a/apps/meteor/client/views/admin/customEmoji/EditCustomEmojiWithData.tsx b/apps/meteor/client/views/admin/customEmoji/EditCustomEmojiWithData.tsx index f43babbfb05c..8bff47185cb7 100644 --- a/apps/meteor/client/views/admin/customEmoji/EditCustomEmojiWithData.tsx +++ b/apps/meteor/client/views/admin/customEmoji/EditCustomEmojiWithData.tsx @@ -1,7 +1,7 @@ import { Box, Button, ButtonGroup, Skeleton, Throbber, InputBox, Callout } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { useMemo, FC } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { AsyncStatePhase } from '../../../hooks/useAsyncState'; import { useEndpointData } from '../../../hooks/useEndpointData'; import EditCustomEmoji from './EditCustomEmoji'; diff --git a/apps/meteor/client/views/admin/customSounds/AddCustomSound.tsx b/apps/meteor/client/views/admin/customSounds/AddCustomSound.tsx index 0b53670c1390..8f9669a9ef1a 100644 --- a/apps/meteor/client/views/admin/customSounds/AddCustomSound.tsx +++ b/apps/meteor/client/views/admin/customSounds/AddCustomSound.tsx @@ -1,10 +1,8 @@ import { Field, TextInput, Box, Icon, Margins, Button, ButtonGroup } from '@rocket.chat/fuselage'; +import { useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useState, useCallback, ReactElement, FormEvent } from 'react'; import VerticalBar from '../../../components/VerticalBar'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useFileInput } from '../../../hooks/useFileInput'; import { validate, createSoundData, soundDataType } from './lib'; diff --git a/apps/meteor/client/views/admin/customSounds/AdminSoundsRoute.tsx b/apps/meteor/client/views/admin/customSounds/AdminSoundsRoute.tsx index 03441862c987..e489eb7b3eeb 100644 --- a/apps/meteor/client/views/admin/customSounds/AdminSoundsRoute.tsx +++ b/apps/meteor/client/views/admin/customSounds/AdminSoundsRoute.tsx @@ -1,5 +1,6 @@ import { Box, Button, Icon, Pagination } from '@rocket.chat/fuselage'; import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; +import { useCustomSound, useRoute, useRouteParameter, usePermission, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useMemo, useState, useCallback, ReactElement } from 'react'; import FilterByText from '../../../components/FilterByText'; @@ -14,10 +15,6 @@ import { usePagination } from '../../../components/GenericTable/hooks/usePaginat import { useSort } from '../../../components/GenericTable/hooks/useSort'; import Page from '../../../components/Page'; import VerticalBar from '../../../components/VerticalBar'; -import { usePermission } from '../../../contexts/AuthorizationContext'; -import { useCustomSound } from '../../../contexts/CustomSoundContext'; -import { useRoute, useRouteParameter } from '../../../contexts/RouterContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useEndpointData } from '../../../hooks/useEndpointData'; import { AsyncStatePhase } from '../../../lib/asyncState'; import NotAuthorizedPage from '../../notAuthorized/NotAuthorizedPage'; diff --git a/apps/meteor/client/views/admin/customSounds/EditSound.tsx b/apps/meteor/client/views/admin/customSounds/EditSound.tsx index 18f5d3ad8d4e..010f12c28f30 100644 --- a/apps/meteor/client/views/admin/customSounds/EditSound.tsx +++ b/apps/meteor/client/views/admin/customSounds/EditSound.tsx @@ -1,12 +1,9 @@ import { Box, Button, ButtonGroup, Margins, TextInput, Field, Icon } from '@rocket.chat/fuselage'; +import { useSetModal, useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useCallback, useState, useMemo, useEffect, ReactElement, SyntheticEvent } from 'react'; import GenericModal from '../../../components/GenericModal'; import VerticalBar from '../../../components/VerticalBar'; -import { useSetModal } from '../../../contexts/ModalContext'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { useFileInput } from '../../../hooks/useFileInput'; import { validate, createSoundData } from './lib'; diff --git a/apps/meteor/client/views/admin/customUserStatus/AddCustomUserStatus.tsx b/apps/meteor/client/views/admin/customUserStatus/AddCustomUserStatus.tsx deleted file mode 100644 index e81533603e6a..000000000000 --- a/apps/meteor/client/views/admin/customUserStatus/AddCustomUserStatus.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { Button, ButtonGroup, TextInput, Field, Select, SelectOption } from '@rocket.chat/fuselage'; -import React, { ReactElement, SyntheticEvent, useCallback, useState } from 'react'; - -import VerticalBar from '../../../components/VerticalBar'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; - -type AddCustomUserStatusProps = { - goToNew: (id: string) => () => void; - close: () => void; - onChange: () => void; -}; - -function AddCustomUserStatus({ goToNew, close, onChange, ...props }: AddCustomUserStatusProps): ReactElement { - const t = useTranslation(); - const dispatchToastMessage = useToastMessageDispatch(); - - const [name, setName] = useState(''); - const [statusType, setStatusType] = useState('online'); - - const saveStatus = useMethod('insertOrUpdateUserStatus'); - const handleSave = useCallback(async () => { - try { - const result = await saveStatus({ - name, - statusType, - }); - dispatchToastMessage({ - type: 'success', - message: t('Custom_User_Status_Updated_Successfully'), - }); - goToNew(result)(); - onChange(); - } catch (error) { - dispatchToastMessage({ type: 'error', message: String(error) }); - } - }, [dispatchToastMessage, goToNew, name, onChange, saveStatus, statusType, t]); - - const presenceOptions: SelectOption[] = [ - ['online', t('Online')], - ['busy', t('Busy')], - ['away', t('Away')], - ['offline', t('Offline')], - ]; - - return ( - - - {t('Name')} - - ): void => setName(e.currentTarget.value)} - placeholder={t('Name')} - /> - - - - {t('Presence')} - - } + /> + + {errors?.statusType && {t('error-the-field-is-required', { field: t('Presence') })}} + + + + + + + + + + {_id && ( + + + + + + + + )} + + ); +}; + +export default CustomUserStatusForm; diff --git a/apps/meteor/client/views/admin/customUserStatus/EditCustomUserStatusWithData.tsx b/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusFormWithData.tsx similarity index 50% rename from apps/meteor/client/views/admin/customUserStatus/EditCustomUserStatusWithData.tsx rename to apps/meteor/client/views/admin/customUserStatus/CustomUserStatusFormWithData.tsx index 8fe62b626e6b..ace27c478ec8 100644 --- a/apps/meteor/client/views/admin/customUserStatus/EditCustomUserStatusWithData.tsx +++ b/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusFormWithData.tsx @@ -1,26 +1,36 @@ -import { Box, Button, ButtonGroup, Skeleton, Throbber, InputBox } from '@rocket.chat/fuselage'; -import React, { useMemo, FC } from 'react'; +import { IUserStatus } from '@rocket.chat/core-typings'; +import { Box, Button, ButtonGroup, Skeleton, Throbber, InputBox, Callout } from '@rocket.chat/fuselage'; +import { useTranslation } from '@rocket.chat/ui-contexts'; +import React, { useMemo, ReactElement } from 'react'; -import { useTranslation } from '../../../contexts/TranslationContext'; import { AsyncStatePhase } from '../../../hooks/useAsyncState'; import { useEndpointData } from '../../../hooks/useEndpointData'; -import EditCustomUserStatus from './EditCustomUserStatus'; +import CustomUserStatusForm from './CustomUserStatusForm'; -type EditCustomUserStatusWithDataProps = { - _id: string | undefined; - close: () => void; - onChange: () => void; +type CustomUserStatusFormWithDataProps = { + _id?: IUserStatus['_id']; + onClose: () => void; + onReload: () => void; }; -export const EditCustomUserStatusWithData: FC = ({ _id, onChange, ...props }) => { +const CustomUserStatusFormWithData = ({ _id, onReload, onClose }: CustomUserStatusFormWithDataProps): ReactElement => { const t = useTranslation(); const query = useMemo(() => ({ query: JSON.stringify({ _id }) }), [_id]); const { value: data, phase: state, error, reload } = useEndpointData('custom-user-status.list', query); + const handleReload = (): void => { + onReload?.(); + reload?.(); + }; + + if (!_id) { + return ; + } + if (state === AsyncStatePhase.LOADING) { return ( - + @@ -44,18 +54,13 @@ export const EditCustomUserStatusWithData: FC if (error || !data || data.statuses.length < 1) { return ( - - {t('Custom_User_Status_Error_Invalid_User_Status')} + + {t('Custom_User_Status_Error_Invalid_User_Status')} ); } - const handleChange = (): void => { - onChange?.(); - reload?.(); - }; - - return ; + return ; }; -export default EditCustomUserStatusWithData; +export default CustomUserStatusFormWithData; diff --git a/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusRoute.tsx b/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusRoute.tsx index 34989a0e865b..89695f9f648d 100644 --- a/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusRoute.tsx +++ b/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusRoute.tsx @@ -1,61 +1,27 @@ import { Button, Icon } from '@rocket.chat/fuselage'; -import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; -import React, { useMemo, useState, useCallback, ReactNode } from 'react'; +import { useRoute, useRouteParameter, usePermission, useTranslation } from '@rocket.chat/ui-contexts'; +import React, { useCallback, ReactNode, useRef } from 'react'; import Page from '../../../components/Page'; import VerticalBar from '../../../components/VerticalBar'; -import { usePermission } from '../../../contexts/AuthorizationContext'; -import { useRoute, useRouteParameter } from '../../../contexts/RouterContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; -import { useEndpointData } from '../../../hooks/useEndpointData'; -import { AsyncStatePhase } from '../../../lib/asyncState'; import NotAuthorizedPage from '../../notAuthorized/NotAuthorizedPage'; -import AddCustomUserStatus from './AddCustomUserStatus'; -import CustomUserStatus, { paramsType, SortType } from './CustomUserStatus'; -import EditCustomUserStatusWithData from './EditCustomUserStatusWithData'; +import CustomUserStatusFormWithData from './CustomUserStatusFormWithData'; +import CustomUserStatusTable from './CustomUserStatusTable'; -function CustomUserStatusRoute(): ReactNode { +const CustomUserStatusRoute = (): ReactNode => { + const t = useTranslation(); const route = useRoute('custom-user-status'); const context = useRouteParameter('context'); const id = useRouteParameter('id'); const canManageUserStatus = usePermission('manage-user-status'); - const t = useTranslation(); - - const [params, setParams] = useState(() => ({ text: '', current: 0, itemsPerPage: 25 })); - const [sort, setSort] = useState(() => ['name', 'asc']); - - const { text, itemsPerPage, current } = useDebouncedValue(params, 500); - const [column, direction] = useDebouncedValue(sort, 500); - const query = useMemo( - () => ({ - query: JSON.stringify({ name: { $regex: text || '', $options: 'i' } }), - sort: JSON.stringify({ [column]: direction === 'asc' ? 1 : -1 }), - ...(itemsPerPage && { count: itemsPerPage }), - ...(current && { offset: current }), - }), - [text, itemsPerPage, current, column, direction], - ); - - const { reload, ...result } = useEndpointData('custom-user-status.list', query); - - const handleItemClick = (id: string) => (): void => { + const handleItemClick = (id: string): void => { route.push({ context: 'edit', id, }); }; - const handleHeaderClick = (id: SortType[0]): void => { - setSort(([sortBy, sortDirection]) => { - if (sortBy === id) { - return [id, sortDirection === 'asc' ? 'desc' : 'asc']; - } - - return [id, 'asc']; - }); - }; - const handleNewButtonClick = useCallback(() => { route.push({ context: 'new' }); }, [route]); @@ -64,18 +30,16 @@ function CustomUserStatusRoute(): ReactNode { route.push({}); }, [route]); - const handleChange = useCallback(() => { - reload(); + const reload = useRef(() => null); + + const handleReload = useCallback(() => { + reload.current(); }, [reload]); if (!canManageUserStatus) { return ; } - if (result.phase === AsyncStatePhase.LOADING || result.phase === AsyncStatePhase.REJECTED) { - return null; - } - return ( @@ -85,30 +49,20 @@ function CustomUserStatusRoute(): ReactNode { - + {context && ( - {context === 'edit' && t('Custom_User_Status_Edit')} - {context === 'new' && t('Custom_User_Status_Add')} + {context === 'edit' ? t('Custom_User_Status_Edit') : t('Custom_User_Status_Add')} - - {context === 'edit' && } - {context === 'new' && } + )} ); -} +}; export default CustomUserStatusRoute; diff --git a/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusTable/CustomUserStatusRow.tsx b/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusTable/CustomUserStatusRow.tsx new file mode 100644 index 000000000000..958f51f5ad20 --- /dev/null +++ b/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusTable/CustomUserStatusRow.tsx @@ -0,0 +1,37 @@ +import { IUserStatus } from '@rocket.chat/core-typings'; +import { TableRow, TableCell } from '@rocket.chat/fuselage'; +import React, { CSSProperties, ReactElement } from 'react'; + +import MarkdownText from '../../../../components/MarkdownText'; + +const style: CSSProperties = { whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }; + +type CustomUserStatusRowProps = { + status: IUserStatus; + onClick: (id: string) => void; +}; + +const CustomUserStatusRow = ({ status, onClick }: CustomUserStatusRowProps): ReactElement => { + const { _id, name, statusType } = status; + + return ( + onClick(_id)} + onClick={(): void => onClick(_id)} + tabIndex={0} + role='link' + action + qa-user-id={_id} + > + + + + + {statusType} + + + ); +}; + +export default CustomUserStatusRow; diff --git a/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusTable/CustomUserStatusTable.tsx b/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusTable/CustomUserStatusTable.tsx new file mode 100644 index 000000000000..4407b664695a --- /dev/null +++ b/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusTable/CustomUserStatusTable.tsx @@ -0,0 +1,103 @@ +import { States, StatesIcon, StatesTitle, Pagination } from '@rocket.chat/fuselage'; +import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; +import { useTranslation } from '@rocket.chat/ui-contexts'; +import React, { ReactElement, useState, useMemo, MutableRefObject, useEffect } from 'react'; + +import FilterByText from '../../../../components/FilterByText'; +import { + GenericTable, + GenericTableHeader, + GenericTableHeaderCell, + GenericTableBody, + GenericTableLoadingTable, +} from '../../../../components/GenericTable'; +import { usePagination } from '../../../../components/GenericTable/hooks/usePagination'; +import { useSort } from '../../../../components/GenericTable/hooks/useSort'; +import { useEndpointData } from '../../../../hooks/useEndpointData'; +import { AsyncStatePhase } from '../../../../lib/asyncState'; +import CustomUserStatusRow from './CustomUserStatusRow'; + +type CustomUserStatusProps = { + reload: MutableRefObject<() => void>; + onClick: (id: string) => void; +}; + +const CustomUserStatus = ({ reload, onClick }: CustomUserStatusProps): ReactElement | null => { + const t = useTranslation(); + const [text, setText] = useState(''); + const { current, itemsPerPage, setItemsPerPage: onSetItemsPerPage, setCurrent: onSetCurrent, ...paginationProps } = usePagination(); + const { sortBy, sortDirection, setSort } = useSort<'name' | 'statusType'>('name'); + + const query = useDebouncedValue( + useMemo( + () => ({ + query: JSON.stringify({ name: { $regex: text || '', $options: 'i' } }), + sort: `{ "${sortBy}": ${sortDirection === 'asc' ? 1 : -1} }`, + count: itemsPerPage, + offset: current, + }), + [text, itemsPerPage, current, sortBy, sortDirection], + ), + 500, + ); + + const { value, reload: reloadEndpoint, phase } = useEndpointData('custom-user-status.list', query); + + useEffect(() => { + reload.current = reloadEndpoint; + }, [reload, reloadEndpoint]); + + if (phase === AsyncStatePhase.REJECTED) { + return null; + } + + return ( + <> + setText(text)} /> + {value?.statuses.length === 0 && ( + + + {t('No_results_found')} + + )} + {value?.statuses && value.statuses.length > 0 && ( + <> + + + + {t('Name')} + + + {t('Presence')} + + + + {phase === AsyncStatePhase.LOADING && } + {value?.statuses.map((status) => ( + + ))} + + + {phase === AsyncStatePhase.RESOLVED && ( + + )} + + )} + + ); +}; + +export default CustomUserStatus; diff --git a/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusTable/index.ts b/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusTable/index.ts new file mode 100644 index 000000000000..814ae75ec5a9 --- /dev/null +++ b/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusTable/index.ts @@ -0,0 +1 @@ +export { default } from './CustomUserStatusTable'; diff --git a/apps/meteor/client/views/admin/customUserStatus/EditCustomUserStatus.tsx b/apps/meteor/client/views/admin/customUserStatus/EditCustomUserStatus.tsx deleted file mode 100644 index 64801f6153f7..000000000000 --- a/apps/meteor/client/views/admin/customUserStatus/EditCustomUserStatus.tsx +++ /dev/null @@ -1,147 +0,0 @@ -import { Button, ButtonGroup, TextInput, Field, Select, Icon, SelectOption } from '@rocket.chat/fuselage'; -import React, { useCallback, useState, useMemo, useEffect, ReactElement, SyntheticEvent } from 'react'; - -import GenericModal from '../../../components/GenericModal'; -import VerticalBar from '../../../components/VerticalBar'; -import { useSetModal } from '../../../contexts/ModalContext'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useTranslation } from '../../../contexts/TranslationContext'; - -type EditCustomUserStatusProps = { - close: () => void; - onChange: () => void; - data?: { - _id: string; - name: string; - statusType: string; - }; -}; -export function EditCustomUserStatus({ close, onChange, data, ...props }: EditCustomUserStatusProps): ReactElement { - const t = useTranslation(); - const dispatchToastMessage = useToastMessageDispatch(); - const setModal = useSetModal(); - - const { _id, name: previousName, statusType: previousStatusType } = data || {}; - - const [name, setName] = useState(() => data?.name ?? ''); - const [statusType, setStatusType] = useState(() => data?.statusType ?? ''); - - useEffect(() => { - setName(previousName || ''); - setStatusType(previousStatusType || ''); - }, [previousName, previousStatusType, _id]); - - const saveStatus = useMethod('insertOrUpdateUserStatus'); - const deleteStatus = useMethod('deleteCustomUserStatus'); - - const hasUnsavedChanges = useMemo( - () => previousName !== name || previousStatusType !== statusType, - [name, previousName, previousStatusType, statusType], - ); - const handleSave = useCallback(async () => { - try { - await saveStatus({ - _id, - previousName, - previousStatusType, - name, - statusType, - }); - dispatchToastMessage({ - type: 'success', - message: t('Custom_User_Status_Updated_Successfully'), - }); - onChange(); - } catch (error) { - dispatchToastMessage({ type: 'error', message: String(error) }); - } - }, [saveStatus, _id, previousName, previousStatusType, name, statusType, dispatchToastMessage, t, onChange]); - - const handleDeleteButtonClick = useCallback(() => { - const handleClose = (): void => { - setModal(null); - close(); - onChange(); - }; - - const handleDelete = async (): Promise => { - try { - await deleteStatus(_id); - setModal(() => ( - - {t('Custom_User_Status_Has_Been_Deleted')} - - )); - } catch (error) { - dispatchToastMessage({ type: 'error', message: String(error) }); - onChange(); - } - }; - - const handleCancel = (): void => { - setModal(null); - }; - - setModal(() => ( - - {t('Custom_User_Status_Delete_Warning')} - - )); - }, [_id, close, deleteStatus, dispatchToastMessage, onChange, setModal, t]); - - const presenceOptions: SelectOption[] = [ - ['online', t('Online')], - ['busy', t('Busy')], - ['away', t('Away')], - ['offline', t('Offline')], - ]; - - return ( - - - {t('Name')} - - ): void => setName(e.currentTarget.value)} - placeholder={t('Name')} - /> - - - - {t('Presence')} - -