diff --git a/.eslintignore b/.eslintignore index 5831f3fab82..6a5d7fc9b82 100644 --- a/.eslintignore +++ b/.eslintignore @@ -18,3 +18,5 @@ imports/client/ !/.storybook/ ee/server/services/dist/** !/.mocharc.js +!/client/.eslintrc.js +!/ee/client/.eslintrc.js diff --git a/.storybook/main.js b/.storybook/main.js index ecfbbfab389..a374e09f945 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,3 +1,7 @@ +const path = require('path'); + +const webpack = require('webpack'); + module.exports = { stories: [ '../app/**/*.stories.js', @@ -6,5 +10,70 @@ module.exports = { ], addons: [ '@storybook/addon-essentials', + '@storybook/addon-postcss', ], + webpackFinal: async (config) => { + const cssRule = config.module.rules.find(({ test }) => test.test('index.css')); + + cssRule.use[2].options = { + ...cssRule.use[2].options, + postcssOptions: { + plugins: [ + require('postcss-custom-properties')({ preserve: true }), + require('postcss-media-minmax')(), + require('postcss-selector-not')(), + require('postcss-nested')(), + require('autoprefixer')(), + require('postcss-url')({ url: ({ absolutePath, relativePath, url }) => { + const absoluteDir = absolutePath.slice(0, -relativePath.length); + const relativeDir = path.relative(absoluteDir, path.resolve(__dirname, '../public')); + const newPath = path.join(relativeDir, url); + return newPath; + } }), + ], + }, + }; + + config.module.rules.push({ + test: /\.info$/, + type: 'json', + }); + + config.module.rules.push({ + test: /\.html$/, + use: '@settlin/spacebars-loader', + }); + + config.module.rules.push({ + test: /\.(ts|tsx)$/, + use: [ + { + loader: 'ts-loader', + options: { + compilerOptions: { + noEmit: false, + }, + }, + }, + ], + }); + + config.resolve.extensions.push('.ts', '.tsx'); + + config.plugins.push( + new webpack.NormalModuleReplacementPlugin( + /^meteor/, + require.resolve('./mocks/meteor.js'), + ), + new webpack.NormalModuleReplacementPlugin( + /(app)\/*.*\/(server)\/*/, + require.resolve('./mocks/empty.js'), + ), + ); + + config.mode = 'development'; + config.optimization.usedExports = true; + + return config; + }, }; diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js deleted file mode 100644 index 65e19305d63..00000000000 --- a/.storybook/webpack.config.js +++ /dev/null @@ -1,65 +0,0 @@ -'use strict'; - -const path = require('path'); - -const webpack = require('webpack'); - -module.exports = async ({ config }) => { - const cssRule = config.module.rules.find(({ test }) => test.test('index.css')); - - cssRule.use[2].options.plugins = [ - require('postcss-custom-properties')({ preserve: true }), - require('postcss-media-minmax')(), - require('postcss-selector-not')(), - require('postcss-nested')(), - require('autoprefixer')(), - require('postcss-url')({ url: ({ absolutePath, relativePath, url }) => { - const absoluteDir = absolutePath.slice(0, -relativePath.length); - const relativeDir = path.relative(absoluteDir, path.resolve(__dirname, '../public')); - const newPath = path.join(relativeDir, url); - return newPath; - } }), - ]; - - config.module.rules.push({ - test: /\.info$/, - type: 'json', - }); - - config.module.rules.push({ - test: /\.html$/, - use: '@settlin/spacebars-loader', - }); - - config.module.rules.push({ - test: /\.(ts|tsx)$/, - use: [ - { - loader: 'ts-loader', - options: { - compilerOptions: { - noEmit: false, - }, - }, - }, - ], - }); - - config.resolve.extensions.push('.ts', '.tsx'); - - config.plugins.push( - new webpack.NormalModuleReplacementPlugin( - /^meteor/, - require.resolve('./mocks/meteor.js'), - ), - new webpack.NormalModuleReplacementPlugin( - /(app)\/*.*\/(server)\/*/, - require.resolve('./mocks/empty.js'), - ), - ); - - config.mode = 'development'; - config.optimization.usedExports = true; - - return config; -}; diff --git a/app/authorization/client/index.js b/app/authorization/client/index.js index bf484b06455..04692ed0749 100644 --- a/app/authorization/client/index.js +++ b/app/authorization/client/index.js @@ -1,7 +1,6 @@ import { hasAllPermission, hasAtLeastOnePermission, hasPermission, userHasAllPermission } from './hasPermission'; import { hasRole } from './hasRole'; import { AuthorizationUtils } from '../lib/AuthorizationUtils'; -import './usersNameChanged'; import './requiresPermission.html'; import './startup'; diff --git a/app/authorization/client/usersNameChanged.js b/app/authorization/client/usersNameChanged.js deleted file mode 100644 index c498ca472b3..00000000000 --- a/app/authorization/client/usersNameChanged.js +++ /dev/null @@ -1,18 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -import { Notifications } from '../../notifications'; -import { RoomRoles } from '../../models'; - -Meteor.startup(function() { - Notifications.onLogged('Users:NameChanged', function({ _id, name }) { - RoomRoles.update({ - 'u._id': _id, - }, { - $set: { - 'u.name': name, - }, - }, { - multi: true, - }); - }); -}); diff --git a/app/channel-settings/client/index.js b/app/channel-settings/client/index.js index 64b7f76be00..3e8041d42ce 100644 --- a/app/channel-settings/client/index.js +++ b/app/channel-settings/client/index.js @@ -1,5 +1,3 @@ -import './startup/messageTypes'; -import './startup/tabBar'; -import './views/Multiselect'; +import './tabBar'; export { ChannelSettings } from './lib/ChannelSettings'; diff --git a/app/channel-settings/client/startup/messageTypes.js b/app/channel-settings/client/startup/messageTypes.js deleted file mode 100644 index e693779180f..00000000000 --- a/app/channel-settings/client/startup/messageTypes.js +++ /dev/null @@ -1,67 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -import { escapeHTML } from '../../../../lib/escapeHTML'; -import { MessageTypes } from '../../../ui-utils'; -import { t } from '../../../utils'; - -Meteor.startup(function() { - MessageTypes.registerType({ - id: 'room_changed_privacy', - system: true, - message: 'room_changed_privacy', - data(message) { - return { - user_by: message.u && message.u.username, - room_type: t(message.msg), - }; - }, - }); - - MessageTypes.registerType({ - id: 'room_changed_topic', - system: true, - message: 'room_changed_topic', - data(message) { - return { - user_by: message.u && message.u.username, - room_topic: escapeHTML(message.msg || `(${ t('None').toLowerCase() })`), - }; - }, - }); - - MessageTypes.registerType({ - id: 'room_changed_avatar', - system: true, - message: 'room_changed_avatar', - data(message) { - return { - user_by: message.u && message.u.username, - }; - }, - }); - - - MessageTypes.registerType({ - id: 'room_changed_announcement', - system: true, - message: 'room_changed_announcement', - data(message) { - return { - user_by: message.u && message.u.username, - room_announcement: escapeHTML(message.msg || `(${ t('None').toLowerCase() })`), - }; - }, - }); - - MessageTypes.registerType({ - id: 'room_changed_description', - system: true, - message: 'room_changed_description', - data(message) { - return { - user_by: message.u && message.u.username, - room_description: escapeHTML(message.msg || `(${ t('None').toLowerCase() })`), - }; - }, - }); -}); diff --git a/app/channel-settings/client/startup/tabBar.ts b/app/channel-settings/client/tabBar.ts similarity index 56% rename from app/channel-settings/client/startup/tabBar.ts rename to app/channel-settings/client/tabBar.ts index e655852ae58..e94f08c7b17 100644 --- a/app/channel-settings/client/startup/tabBar.ts +++ b/app/channel-settings/client/tabBar.ts @@ -1,6 +1,6 @@ import { FC, lazy, LazyExoticComponent } from 'react'; -import { addAction } from '../../../../client/views/room/lib/Toolbox'; +import { addAction } from '../../../client/views/room/lib/Toolbox'; addAction('channel-settings', { groups: ['channel', 'group'], @@ -9,6 +9,6 @@ addAction('channel-settings', { full: true, title: 'Room_Info', icon: 'info-circled', - template: lazy(() => import('../../../../client/views/room/contextualBar/Info')) as LazyExoticComponent, + template: lazy(() => import('../../../client/views/room/contextualBar/Info')) as LazyExoticComponent, order: 7, }); diff --git a/app/channel-settings/client/views/Multiselect.js b/app/channel-settings/client/views/Multiselect.js deleted file mode 100644 index 1f90cc45a38..00000000000 --- a/app/channel-settings/client/views/Multiselect.js +++ /dev/null @@ -1,12 +0,0 @@ -import { HTML } from 'meteor/htmljs'; - -import { createTemplateForComponent } from '../../../../client/reactAdapters'; - -createTemplateForComponent( - 'Multiselect', - () => import('../../../../client/admin/settings/inputs/MultiSelectSettingInput'), - { - // eslint-disable-next-line new-cap - renderContainerView: () => HTML.DIV({ class: 'rc-multiselect', style: 'display: flex;' }), - }, -); diff --git a/app/chatpal-search/client/route.js b/app/chatpal-search/client/route.js index 91f718f1498..8f9905b8b63 100644 --- a/app/chatpal-search/client/route.js +++ b/app/chatpal-search/client/route.js @@ -1,5 +1,4 @@ -import { BlazeLayout } from 'meteor/kadira:blaze-layout'; - +import * as BlazeLayout from '../../../client/lib/portals/blazeLayout'; import { registerAdminRoute } from '../../../client/views/admin'; import { t } from '../../utils'; diff --git a/app/livechat/client/tabBar.ts b/app/livechat/client/tabBar.ts index 0e1240d56a5..1ef8df95426 100644 --- a/app/livechat/client/tabBar.ts +++ b/app/livechat/client/tabBar.ts @@ -7,7 +7,7 @@ addAction('room-info', { id: 'room-info', title: 'Room_Info', icon: 'info-circled', - template: lazy(() => import('../../../client/omnichannel/chats/contextualBar')), + template: lazy(() => import('../../../client/views/omnichannel/directory/chats/contextualBar/ChatsContextualBar')), order: 0, }); diff --git a/app/livestream/client/tabBar.tsx b/app/livestream/client/tabBar.tsx index f3d39198578..33e1fbb997d 100644 --- a/app/livestream/client/tabBar.tsx +++ b/app/livestream/client/tabBar.tsx @@ -1,4 +1,4 @@ -import React, { useMemo } from 'react'; +import React, { ReactNode, useMemo } from 'react'; import { Option, Badge } from '@rocket.chat/fuselage'; import { useSetting } from '../../../client/contexts/SettingsContext'; @@ -19,10 +19,10 @@ addAction('livestream', ({ room }) => { icon: 'podcast', template: 'liveStreamTab', order: isLive ? -1 : 15, - renderAction: (props): React.ReactNode => + renderAction: (props): ReactNode => {isLive ? ! : null} , - renderOption: ({ label: { title, icon }, ...props }: any): React.ReactNode => , } : null), [enabled, isLive, t]); diff --git a/app/mail-messages/client/router.js b/app/mail-messages/client/router.js index 73bb53fac23..4f603b16436 100644 --- a/app/mail-messages/client/router.js +++ b/app/mail-messages/client/router.js @@ -1,6 +1,7 @@ import { Meteor } from 'meteor/meteor'; import { FlowRouter } from 'meteor/kadira:flow-router'; -import { BlazeLayout } from 'meteor/kadira:blaze-layout'; + +import * as BlazeLayout from '../../../client/lib/portals/blazeLayout'; FlowRouter.route('/mailer/unsubscribe/:_id/:createdAt', { name: 'mailer-unsubscribe', diff --git a/app/message-snippet/client/router.js b/app/message-snippet/client/router.js index 79c4ab0acc1..9bf90c1f10c 100644 --- a/app/message-snippet/client/router.js +++ b/app/message-snippet/client/router.js @@ -1,5 +1,6 @@ import { FlowRouter } from 'meteor/kadira:flow-router'; -import { BlazeLayout } from 'meteor/kadira:blaze-layout'; + +import * as BlazeLayout from '../../../client/lib/portals/blazeLayout'; FlowRouter.route('/snippet/:snippetId/:snippetName', { name: 'snippetView', diff --git a/app/oauth2-server-config/client/oauth/oauth2-client.js b/app/oauth2-server-config/client/oauth/oauth2-client.js index e913bf14a5c..1a44456b72e 100644 --- a/app/oauth2-server-config/client/oauth/oauth2-client.js +++ b/app/oauth2-server-config/client/oauth/oauth2-client.js @@ -1,10 +1,10 @@ import { Meteor } from 'meteor/meteor'; import { FlowRouter } from 'meteor/kadira:flow-router'; -import { BlazeLayout } from 'meteor/kadira:blaze-layout'; import { Template } from 'meteor/templating'; import { Accounts } from 'meteor/accounts-base'; import { ReactiveVar } from 'meteor/reactive-var'; +import * as BlazeLayout from '../../../../client/lib/portals/blazeLayout'; import { APIClient } from '../../../utils/client'; FlowRouter.route('/oauth/authorize', { diff --git a/app/otr/client/rocketchat.otr.room.js b/app/otr/client/rocketchat.otr.room.js index 221d6a9d0de..b887082210e 100644 --- a/app/otr/client/rocketchat.otr.room.js +++ b/app/otr/client/rocketchat.otr.room.js @@ -3,7 +3,6 @@ import { ReactiveVar } from 'meteor/reactive-var'; import { Random } from 'meteor/random'; import { EJSON } from 'meteor/ejson'; import { Tracker } from 'meteor/tracker'; -import { FlowRouter } from 'meteor/kadira:flow-router'; import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; import { TimeSync } from 'meteor/mizzao:timesync'; import _ from 'underscore'; @@ -14,6 +13,7 @@ import { Notifications } from '../../notifications'; import { modal } from '../../ui-utils'; import { getUidDirectMessage } from '../../ui-utils/client/lib/getUidDirectMessage'; import { Presence } from '../../../client/lib/presence'; +import { goToRoomById } from '../../../client/lib/goToRoomById'; OTR.Room = class { constructor(userId, roomId) { @@ -189,7 +189,7 @@ OTR.Room = class { this.generateKeyPair().then(() => { this.importPublicKey(data.publicKey).then(() => { this.firstPeer = false; - FlowRouter.goToRoomById(data.roomId); + goToRoomById(data.roomId); Meteor.defer(() => { this.established.set(true); this.acknowledge(); diff --git a/app/search/client/provider/result.js b/app/search/client/provider/result.js index 00a6eaee78a..ff2cc972bf1 100644 --- a/app/search/client/provider/result.js +++ b/app/search/client/provider/result.js @@ -11,6 +11,7 @@ import { MessageAction, RoomHistoryManager } from '../../../ui-utils'; import { messageArgs } from '../../../ui-utils/client/lib/messageArgs'; import { Rooms } from '../../../models/client'; import { getCommonRoomEvents } from '../../../ui/client/views/app/lib/getCommonRoomEvents'; +import { goToRoomById } from '../../../../client/lib/goToRoomById'; Meteor.startup(function() { MessageAction.addButton({ @@ -35,7 +36,7 @@ Meteor.startup(function() { return RoomHistoryManager.getSurroundingMessages(message, 50); } - FlowRouter.goToRoomById(message.rid); + goToRoomById(message.rid); // RocketChat.MessageAction.hideDropDown(); if (window.matchMedia('(max-width: 500px)').matches) { diff --git a/imports/message-read-receipt/client/readReceipts.css b/app/theme/client/imports/components/read-receipts.css similarity index 89% rename from imports/message-read-receipt/client/readReceipts.css rename to app/theme/client/imports/components/read-receipts.css index 22788f69166..da73d930416 100644 --- a/imports/message-read-receipt/client/readReceipts.css +++ b/app/theme/client/imports/components/read-receipts.css @@ -5,11 +5,12 @@ } .read-receipt .rc-icon { - height: 0.8em; width: 0.8em; + height: 0.8em; } -.message:hover .read-receipt, .message.active .read-receipt { +.message:hover .read-receipt, +.message.active .read-receipt { display: none; } @@ -20,6 +21,7 @@ .read-receipt.read { color: #1d74f5; color: var(--rc-color-button-primary); + font-style: normal; } @@ -29,13 +31,16 @@ .read-receipts__user { display: flex; - padding: 8px 8px; + + padding: 8px; align-items: center; } .read-receipts__name { flex: 1 1 auto; + margin: 0 10px; + font-size: 16px; } diff --git a/app/theme/client/imports/general/base_old.css b/app/theme/client/imports/general/base_old.css index e65ba2bb351..50c1c337034 100644 --- a/app/theme/client/imports/general/base_old.css +++ b/app/theme/client/imports/general/base_old.css @@ -145,18 +145,6 @@ justify-content: center; } -.connection-status > .alert { - position: absolute; - z-index: 1000000; - top: 0; - - width: 100%; - margin-top: 0 !important; - padding: 2px; - - border-width: 0 0 1px; -} - .rc-old .alert { margin: 1rem 0; padding: 0.5rem; diff --git a/app/theme/client/main.css b/app/theme/client/main.css index 81aea4d296d..7ecf241e098 100644 --- a/app/theme/client/main.css +++ b/app/theme/client/main.css @@ -36,6 +36,7 @@ @import 'imports/components/modal.css'; @import 'imports/components/chip.css'; @import 'imports/components/messages.css'; +@import 'imports/components/read-receipts.css'; @import 'imports/components/contextual-bar.css'; @import 'imports/components/emojiPicker.css'; @import 'imports/components/table.css'; diff --git a/app/threads/client/flextab/thread.js b/app/threads/client/flextab/thread.js index 134af66c45b..96e5092e6e8 100644 --- a/app/threads/client/flextab/thread.js +++ b/app/threads/client/flextab/thread.js @@ -3,7 +3,6 @@ import { Meteor } from 'meteor/meteor'; import { Mongo } from 'meteor/mongo'; import { Template } from 'meteor/templating'; import { Session } from 'meteor/session'; -import { HTML } from 'meteor/htmljs'; import { ReactiveDict } from 'meteor/reactive-dict'; import { Tracker } from 'meteor/tracker'; import { FlowRouter } from 'meteor/kadira:flow-router'; @@ -14,7 +13,6 @@ import { messageContext } from '../../../ui-utils/client/lib/messageContext'; import { upsertMessageBulk } from '../../../ui-utils/client/lib/RoomHistoryManager'; import { Messages } from '../../../models'; import { fileUpload } from '../../../ui/client/lib/fileUpload'; -import { createTemplateForComponent } from '../../../../client/reactAdapters'; import { dropzoneEvents, dropzoneHelpers } from '../../../ui/client/views/app/room'; import './thread.html'; import { getUserPreference } from '../../../utils'; @@ -23,21 +21,8 @@ import { callbacks } from '../../../callbacks/client'; import './messageBoxFollow'; import { getCommonRoomEvents } from '../../../ui/client/views/app/lib/getCommonRoomEvents'; -createTemplateForComponent('Checkbox', async () => { - const { CheckBox } = await import('@rocket.chat/fuselage'); - return { default: CheckBox }; -}, { - // eslint-disable-next-line new-cap - renderContainerView: () => HTML.DIV({ class: 'rcx-checkbox', style: 'display: flex;' }), -}); - const sort = { ts: 1 }; -createTemplateForComponent('ThreadComponent', () => import('../components/ThreadComponent'), { - // eslint-disable-next-line new-cap - renderContainerView: () => HTML.DIV({ class: 'contextual-bar', style: 'display: flex; height: 100%;' }), -}); - Template.thread.events({ ...dropzoneEvents, ...getCommonRoomEvents(), diff --git a/app/token-login/client/login_token_client.js b/app/token-login/client/login_token_client.js index 4809a81f241..6e18bce483e 100644 --- a/app/token-login/client/login_token_client.js +++ b/app/token-login/client/login_token_client.js @@ -1,7 +1,8 @@ import { Meteor } from 'meteor/meteor'; import { Accounts } from 'meteor/accounts-base'; import { FlowRouter } from 'meteor/kadira:flow-router'; -import { BlazeLayout } from 'meteor/kadira:blaze-layout'; + +import * as BlazeLayout from '../../../client/lib/portals/blazeLayout'; Meteor.loginWithLoginToken = function(token) { Accounts.callLoginMethod({ diff --git a/app/ui-login/client/routes.js b/app/ui-login/client/routes.js index 95b6a7ca7c4..247e7696838 100644 --- a/app/ui-login/client/routes.js +++ b/app/ui-login/client/routes.js @@ -1,5 +1,6 @@ import { FlowRouter } from 'meteor/kadira:flow-router'; -import { BlazeLayout } from 'meteor/kadira:blaze-layout'; + +import * as BlazeLayout from '../../../client/lib/portals/blazeLayout'; FlowRouter.route('/reset-password/:token', { name: 'resetPassword', diff --git a/app/ui-master/client/main.html b/app/ui-master/client/main.html index 7b657a62c76..ad1266a7e46 100644 --- a/app/ui-master/client/main.html +++ b/app/ui-master/client/main.html @@ -5,9 +5,6 @@ {{#if subsReady}} {{#unless showSetupWizard}} {{#unless logged}} -
- {{> status}} -
{{#if useIframe}} {{#if iframeUrl}} @@ -40,10 +37,6 @@ {{> Template.dynamic template=center}} - -
- {{> status}} -
{{/if}} {{/if}} {{/unless}} diff --git a/app/ui-master/client/main.js b/app/ui-master/client/main.js index 92ba9766cc4..dd486e4e06f 100644 --- a/app/ui-master/client/main.js +++ b/app/ui-master/client/main.js @@ -17,7 +17,6 @@ import { hasRole } from '../../authorization'; import { tooltip } from '../../ui/client/components/tooltip'; import { callbacks } from '../../callbacks/client'; import { isSyncReady } from '../../../client/lib/userData'; -import { createTemplateForComponent } from '../../../client/reactAdapters'; function executeCustomScript(script) { eval(script);//eslint-disable-line @@ -30,8 +29,6 @@ function customScriptsOnLogout() { } } -createTemplateForComponent('accountSecurity', () => import('../../../client/views/account/security/AccountSecurityPage')); - callbacks.add('afterLogoutCleanUp', () => customScriptsOnLogout(), callbacks.priority.LOW, 'custom-script-on-logout'); Template.body.onRendered(function() { @@ -222,6 +219,11 @@ Template.main.helpers({ return (!userId && Show_Setup_Wizard === 'pending') || (userId && hasRole(userId, 'admin') && Show_Setup_Wizard === 'in_progress'); }, + readReceiptsEnabled() { + if (settings.get('Message_Read_Receipt_Store_Users')) { + return 'read-receipts-enabled'; + } + }, }); Template.main.events({ diff --git a/app/ui-message/client/index.js b/app/ui-message/client/index.js index 879813b2847..ab52f2f87da 100644 --- a/app/ui-message/client/index.js +++ b/app/ui-message/client/index.js @@ -6,4 +6,3 @@ import './popup/messagePopupChannel'; import './popup/messagePopupConfig'; import './popup/messagePopupEmoji'; import './popup/messagePopupSlashCommandPreview'; -import '../../../client/views/blocks'; diff --git a/app/ui-message/client/message.js b/app/ui-message/client/message.js index bb4f59f70ed..3b71f96fd96 100644 --- a/app/ui-message/client/message.js +++ b/app/ui-message/client/message.js @@ -17,12 +17,9 @@ import { AutoTranslate } from '../../autotranslate/client'; import { escapeHTML } from '../../../lib/escapeHTML'; import { renderMentions } from '../../mentions/client/client'; import { renderMessageBody } from '../../../client/lib/renderMessageBody'; -import { createTemplateForComponent } from '../../../client/reactAdapters'; - +import { settings } from '../../settings/client'; import './message.html'; -createTemplateForComponent('messageLocation', () => import('../../../client/views/location/MessageLocation')); - const renderBody = (msg, settings) => { const searchedText = msg.searchedText ? msg.searchedText : ''; const isSystemMessage = MessageTypes.isSystemMessage(msg); @@ -454,6 +451,15 @@ Template.message.helpers({ const { msg } = this; return msg.starred && msg.starred.length > 0 && msg.starred.find((star) => star._id === Meteor.userId()) && !(msg.actionContext === 'starred' || this.context === 'starred'); }, + readReceipt() { + if (!settings.get('Message_Read_Receipt_Enabled')) { + return; + } + + return { + readByEveryone: (!this.msg.unread && 'read') || 'color-component-color', + }; + }, }); const hasTempClass = (node) => node.classList.contains('temp'); diff --git a/app/ui-sidenav/client/sideNav.js b/app/ui-sidenav/client/sideNav.js index 3f2d56bde67..323895a2f28 100644 --- a/app/ui-sidenav/client/sideNav.js +++ b/app/ui-sidenav/client/sideNav.js @@ -1,5 +1,4 @@ import { Meteor } from 'meteor/meteor'; -import { HTML } from 'meteor/htmljs'; import { Tracker } from 'meteor/tracker'; import { ReactiveVar } from 'meteor/reactive-var'; import { FlowRouter } from 'meteor/kadira:flow-router'; @@ -9,10 +8,6 @@ import { SideNav, menu } from '../../ui-utils'; import { settings } from '../../settings'; import { roomTypes, getUserPreference } from '../../utils'; import { Users } from '../../models'; -import { createTemplateForComponent } from '../../../client/reactAdapters'; - -createTemplateForComponent('sidebarHeader', () => import('../../../client/sidebar/header')); -createTemplateForComponent('sidebarChats', () => import('../../../client/sidebar/RoomList'), { renderContainerView: () => HTML.DIV({ style: 'display: flex; flex: 1 1 auto;' }) });// eslint-disable-line new-cap Template.sideNav.helpers({ flexTemplate() { diff --git a/app/ui-sidenav/client/userPresence.js b/app/ui-sidenav/client/userPresence.js index 4c54be3356c..b7e821c104b 100644 --- a/app/ui-sidenav/client/userPresence.js +++ b/app/ui-sidenav/client/userPresence.js @@ -6,7 +6,7 @@ import _ from 'underscore'; import mem from 'mem'; import { APIClient } from '../../utils/client'; -import { saveUser, interestedUserIds } from '../../../imports/startup/client/listenActiveUsers'; +import { saveUser, interestedUserIds } from '../../../client/startup/listenActiveUsers'; import { Presence } from '../../../client/lib/presence'; import './userPresence.html'; diff --git a/app/ui-utils/client/lib/AccountBox.js b/app/ui-utils/client/lib/AccountBox.js index 7216ceec74c..253a1c90a21 100644 --- a/app/ui-utils/client/lib/AccountBox.js +++ b/app/ui-utils/client/lib/AccountBox.js @@ -2,10 +2,10 @@ import { Meteor } from 'meteor/meteor'; import { ReactiveVar } from 'meteor/reactive-var'; import { Tracker } from 'meteor/tracker'; import { FlowRouter } from 'meteor/kadira:flow-router'; -import { BlazeLayout } from 'meteor/kadira:blaze-layout'; import { Session } from 'meteor/session'; import _ from 'underscore'; +import * as BlazeLayout from '../../../../client/lib/portals/blazeLayout'; import { SideNav } from './SideNav'; export const AccountBox = (function() { diff --git a/app/ui-utils/client/lib/MessageAction.js b/app/ui-utils/client/lib/MessageAction.js index c97b52956f9..85426f4dcc4 100644 --- a/app/ui-utils/client/lib/MessageAction.js +++ b/app/ui-utils/client/lib/MessageAction.js @@ -8,9 +8,7 @@ import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; import { ReactiveVar } from 'meteor/reactive-var'; import { Tracker } from 'meteor/tracker'; import { Session } from 'meteor/session'; -import { HTML } from 'meteor/htmljs'; -import { createTemplateForComponent } from '../../../../client/reactAdapters'; import { messageArgs } from './messageArgs'; import { roomTypes, canDeleteMessage } from '../../../utils/client'; import { Messages, Rooms, Subscriptions } from '../../../models/client'; @@ -387,7 +385,3 @@ Meteor.startup(async function() { group: 'menu', }); }); - -createTemplateForComponent('reactionList', () => import('./ReactionListContent'), { - renderContainerView: () => HTML.DIV({ style: 'margin: -16px; height: 100%; display: flex; flex-direction: column; overflow: hidden;' }), // eslint-disable-line new-cap -}); diff --git a/app/ui-utils/client/lib/messageContext.js b/app/ui-utils/client/lib/messageContext.js index 283cddf5bb9..62342c8d93b 100644 --- a/app/ui-utils/client/lib/messageContext.js +++ b/app/ui-utils/client/lib/messageContext.js @@ -11,6 +11,7 @@ import { AutoTranslate } from '../../../autotranslate/client'; import { Layout } from './Layout'; import { fireGlobalEvent } from './fireGlobalEvent'; import { actionLinks } from '../../../action-links/client'; +import { goToRoomById } from '../../../../client/lib/goToRoomById'; const fields = { name: 1, username: 1, 'settings.preferences.showMessageInMainThread': 1, 'settings.preferences.autoImageLoad': 1, 'settings.preferences.saveMobileBandwidth': 1, 'settings.preferences.collapseMediaByDefault': 1, 'settings.preferences.hideRoles': 1 }; @@ -51,7 +52,7 @@ export function messageContext({ rid } = Template.instance()) { const openDiscussion = (e) => { e.preventDefault(); const { drid } = e.currentTarget.dataset; - FlowRouter.goToRoomById(drid); + goToRoomById(drid); }; const replyBroadcast = (e) => { diff --git a/app/ui-utils/client/lib/openRoom.js b/app/ui-utils/client/lib/openRoom.js index 7dc0d4c9f20..204dba8361f 100644 --- a/app/ui-utils/client/lib/openRoom.js +++ b/app/ui-utils/client/lib/openRoom.js @@ -3,11 +3,11 @@ import { Tracker } from 'meteor/tracker'; import { Blaze } from 'meteor/blaze'; import { Template } from 'meteor/templating'; import { FlowRouter } from 'meteor/kadira:flow-router'; -import { BlazeLayout } from 'meteor/kadira:blaze-layout'; import { Session } from 'meteor/session'; import mem from 'mem'; import _ from 'underscore'; +import * as BlazeLayout from '../../../../client/lib/portals/blazeLayout'; import { Messages, ChatSubscription, Rooms } from '../../../models'; import { settings } from '../../../settings'; import { callbacks } from '../../../callbacks'; diff --git a/app/ui/client/components/status.html b/app/ui/client/components/status.html deleted file mode 100644 index 94aa099d749..00000000000 --- a/app/ui/client/components/status.html +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/app/ui/client/components/status.js b/app/ui/client/components/status.js deleted file mode 100644 index df435981ec4..00000000000 --- a/app/ui/client/components/status.js +++ /dev/null @@ -1,66 +0,0 @@ -import _ from 'underscore'; -import { Meteor } from 'meteor/meteor'; -import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { Template } from 'meteor/templating'; - -import './status.html'; - -const retryTime = new ReactiveVar(0); -let retryHandle = null; - -const clearRetryInterval = function() { - clearInterval(retryHandle); - - retryHandle = null; -}; - -const trackStatus = function() { - if (Meteor.status().status === 'waiting') { - retryHandle = retryHandle || setInterval(function() { - const timeDiff = Meteor.status().retryTime - new Date().getTime(); - const _retryTime = (timeDiff > 0 && Math.round(timeDiff / 1000)) || 0; - - retryTime.set(_retryTime); - }, 500); - } else { - clearRetryInterval(); - } -}; - -Template.status.onDestroyed(clearRetryInterval); - -Template.status.onCreated(function() { - this.autorun(trackStatus); -}); - -Template.status.helpers({ - connected() { - return Meteor.status().connected; - }, - - message() { - return TAPi18n.__('meteor_status', { context: Meteor.status().status }); - }, - - extraMessage() { - if (Meteor.status().status === 'waiting') { - return TAPi18n.__('meteor_status_reconnect_in', { count: retryTime.get() }); - } - }, - - showReconnect() { - return _.contains(['waiting', 'offline'], Meteor.status().status); - }, - - reconnectLabel() { - return TAPi18n.__('meteor_status_try_now', { context: Meteor.status().status }); - }, -}); - -Template.status.events({ - 'click a.alert-link'(e) { - e.preventDefault(); - Meteor.reconnect(); - }, -}); diff --git a/app/ui/client/index.js b/app/ui/client/index.js index 8a08c5cdcbf..00cf67b120c 100644 --- a/app/ui/client/index.js +++ b/app/ui/client/index.js @@ -1,5 +1,3 @@ -import { createTemplateForComponent } from '../../../client/reactAdapters'; - import './lib/accounts'; import './lib/collections'; import './lib/iframeCommands'; @@ -37,7 +35,6 @@ import './views/app/videoCall/videoButtons'; import './views/app/videoCall/videoCall'; import './views/app/photoswipe'; import './components/icon'; -import './components/status'; import './components/table.html'; import './components/table'; import './components/tabs'; @@ -58,5 +55,3 @@ export { AudioRecorder } from './lib/recorderjs/audioRecorder'; export { VideoRecorder } from './lib/recorderjs/videoRecorder'; export { chatMessages } from './views/app/room'; export * from './lib/userPopoverStatus'; - -createTemplateForComponent('RoomForeword', () => import('../../../client/components/RoomForeword')); diff --git a/app/ui/client/lib/Tooltip.js b/app/ui/client/lib/Tooltip.js index 07959a79d3c..2a1143811d1 100644 --- a/app/ui/client/lib/Tooltip.js +++ b/app/ui/client/lib/Tooltip.js @@ -1,6 +1,6 @@ import { Tracker } from 'meteor/tracker'; -import { createEphemeralPortal } from '../../../../client/reactAdapters'; +import { createEphemeralPortal } from '../../../../client/lib/portals/createEphemeralPortal'; const Dep = new Tracker.Dependency(); @@ -28,14 +28,14 @@ export const closeTooltip = () => { unregister = unregister && unregister(); }; -export const openToolTip = async (title, anchor) => { +export const openToolTip = (title, anchor) => { dom = dom || createAnchor(); state = { title, anchor, }; Dep.changed(); - unregister = unregister || await createEphemeralPortal(() => import('./TooltipComponent'), props, dom); + unregister = unregister || createEphemeralPortal(() => import('./TooltipComponent'), props, dom); }; document.body.addEventListener('mouseover', (() => { diff --git a/app/ui/client/lib/UserCard.js b/app/ui/client/lib/UserCard.js index fcee56071bf..be6c6c326c4 100644 --- a/app/ui/client/lib/UserCard.js +++ b/app/ui/client/lib/UserCard.js @@ -1,7 +1,7 @@ import { FlowRouter } from 'meteor/kadira:flow-router'; import { Tracker } from 'meteor/tracker'; -import { createEphemeralPortal } from '../../../../client/reactAdapters'; +import { createEphemeralPortal } from '../../../../client/lib/portals/createEphemeralPortal'; const Dep = new Tracker.Dependency(); @@ -35,7 +35,7 @@ export const closeUserCard = () => { }); }; -export const openUserCard = async (args) => { +export const openUserCard = (args) => { props = { ...args, onClose: closeUserCard, @@ -45,7 +45,7 @@ export const openUserCard = async (args) => { container = container || createContainer(); - unregister = unregister || await createEphemeralPortal( + unregister = unregister || createEphemeralPortal( () => import('../../../../client/views/room/UserCard'), () => { Dep.depend(); return props; diff --git a/app/ui/client/views/app/lib/getCommonRoomEvents.js b/app/ui/client/views/app/lib/getCommonRoomEvents.js index 3a28c14094a..c273067e36e 100644 --- a/app/ui/client/views/app/lib/getCommonRoomEvents.js +++ b/app/ui/client/views/app/lib/getCommonRoomEvents.js @@ -21,6 +21,7 @@ import { ChatMessage, Rooms, Messages } from '../../../../../models'; import { t } from '../../../../../utils/client'; import { chatMessages } from '../room'; import { EmojiEvents } from '../../../../../reactions/client/init'; +import { goToRoomById } from '../../../../../../client/lib/goToRoomById'; const mountPopover = (e, i, outerContext) => { let context = $(e.target).parents('.message').data('context'); @@ -313,7 +314,7 @@ export const getCommonRoomEvents = () => ({ if (Layout.isEmbedded()) { fireGlobalEvent('click-mention-link', { path: FlowRouter.path('channel', { name: channel }), channel }); } - FlowRouter.goToRoomById(channel); + goToRoomById(channel); return; } diff --git a/app/videobridge/client/tabBar.tsx b/app/videobridge/client/tabBar.tsx index 7f3fc4beac3..b52fcb20b66 100644 --- a/app/videobridge/client/tabBar.tsx +++ b/app/videobridge/client/tabBar.tsx @@ -1,4 +1,4 @@ -import React, { useMemo, lazy } from 'react'; +import React, { useMemo, lazy, ReactNode } from 'react'; import { useStableArray } from '@rocket.chat/fuselage-hooks'; import { Option, Badge } from '@rocket.chat/fuselage'; @@ -32,10 +32,10 @@ addAction('bbb_video', ({ room }) => { icon: 'phone', template: templateBBB, order: live ? -1 : 0, - renderAction: (props): React.ReactNode => + renderAction: (props): ReactNode => {live ? ! : null} , - renderOption: ({ label: { title, icon }, ...props }: any): React.ReactNode => , + renderOption: ({ label: { title, icon }, ...props }: any): ReactNode => , } : null), [enabled, groups, live, t]); }); @@ -66,10 +66,10 @@ addAction('video', ({ room }) => { template: templateJitsi, full: true, order: live ? -1 : 0, - renderAction: (props): React.ReactNode => + renderAction: (props): ReactNode => {live && !} , - renderOption: ({ label: { title, icon }, ...props }: any): React.ReactNode => , } : null), [enabled, groups, live, t]); diff --git a/app/webrtc/client/WebRTCClass.js b/app/webrtc/client/WebRTCClass.js index 53eed4791b6..67610a6c0b6 100644 --- a/app/webrtc/client/WebRTCClass.js +++ b/app/webrtc/client/WebRTCClass.js @@ -2,7 +2,6 @@ import { Emitter } from '@rocket.chat/emitter'; import { Meteor } from 'meteor/meteor'; import { Tracker } from 'meteor/tracker'; import { ReactiveVar } from 'meteor/reactive-var'; -import { FlowRouter } from 'meteor/kadira:flow-router'; import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; import { ChromeScreenShare } from './screenShare'; @@ -12,6 +11,7 @@ import { settings } from '../../settings'; import { modal } from '../../ui-utils'; import { ChatSubscription } from '../../models'; import { WEB_RTC_EVENTS } from '..'; +import { goToRoomById } from '../../../client/lib/goToRoomById'; class WebRTCTransportClass extends Emitter { constructor(webrtcInstance) { @@ -663,7 +663,7 @@ class WebRTCClass { onRemoteCall(data) { if (this.autoAccept === true) { - FlowRouter.goToRoomById(data.room); + goToRoomById(data.room); Meteor.defer(() => { this.joinCall({ to: data.from, @@ -712,7 +712,7 @@ class WebRTCClass { cancelButtonText: t('No'), }, (isConfirm) => { if (isConfirm) { - FlowRouter.goToRoomById(data.room); + goToRoomById(data.room); return this.joinCall({ to: data.from, monitor: data.monitor, diff --git a/client/.eslintrc.js b/client/.eslintrc.js new file mode 100644 index 00000000000..5f7687c6742 --- /dev/null +++ b/client/.eslintrc.js @@ -0,0 +1,129 @@ +module.exports = { + root: true, + extends: ['@rocket.chat/eslint-config', 'prettier'], + parser: 'babel-eslint', + plugins: ['react', 'react-hooks', 'prettier'], + rules: { + 'import/named': 'error', + 'import/order': [ + 'error', + { + 'newlines-between': 'always', + 'groups': ['builtin', 'external', 'internal', ['parent', 'sibling', 'index']], + 'alphabetize': { + order: 'asc', + }, + }, + ], + 'jsx-quotes': ['error', 'prefer-single'], + 'prefer-arrow-callback': ['error', { allowNamedFunctions: true }], + 'prettier/prettier': 2, + 'react/display-name': 'error', + 'react/jsx-uses-react': 'error', + 'react/jsx-uses-vars': 'error', + 'react/jsx-no-undef': 'error', + 'react/jsx-fragments': ['error', 'syntax'], + 'react/no-multi-comp': 'error', + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': [ + 'warn', + { + additionalHooks: '(useComponentDidUpdate)', + }, + ], + }, + settings: { + 'import/resolver': { + node: { + extensions: ['.js', '.ts', '.tsx'], + }, + }, + 'react': { + version: 'detect', + }, + }, + env: { + browser: true, + es6: true, + }, + overrides: [ + { + files: ['**/*.ts', '**/*.tsx'], + extends: [ + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/eslint-recommended', + '@rocket.chat/eslint-config', + 'prettier', + ], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint', 'react', 'react-hooks', 'prettier'], + rules: { + '@typescript-eslint/ban-ts-ignore': 'off', + '@typescript-eslint/indent': 'off', + '@typescript-eslint/interface-name-prefix': ['error', 'always'], + '@typescript-eslint/no-extra-parens': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + }, + ], + 'func-call-spacing': 'off', + 'indent': 'off', + 'import/order': [ + 'error', + { + 'newlines-between': 'always', + 'groups': ['builtin', 'external', 'internal', ['parent', 'sibling', 'index']], + 'alphabetize': { + order: 'asc', + }, + }, + ], + 'jsx-quotes': ['error', 'prefer-single'], + 'no-extra-parens': 'off', + 'no-spaced-func': 'off', + 'no-unused-vars': 'off', + 'no-useless-constructor': 'off', + 'no-use-before-define': 'off', + 'prefer-arrow-callback': ['error', { allowNamedFunctions: true }], + 'prettier/prettier': 2, + 'react/display-name': 'error', + 'react/jsx-uses-react': 'error', + 'react/jsx-uses-vars': 'error', + 'react/jsx-no-undef': 'error', + 'react/jsx-fragments': ['error', 'syntax'], + 'react/no-multi-comp': 'error', + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': [ + 'warn', + { + additionalHooks: '(useComponentDidUpdate)', + }, + ], + }, + env: { + browser: true, + es6: true, + }, + settings: { + 'import/resolver': { + node: { + extensions: ['.js', '.ts', '.tsx'], + }, + }, + 'react': { + version: 'detect', + }, + }, + }, + { + files: ['**/*.stories.js', '**/*.stories.jsx', '**/*.stories.ts', '**/*.stories.tsx'], + rules: { + 'react/display-name': 'off', + 'react/no-multi-comp': 'off', + }, + }, + ], +}; diff --git a/client/.prettierrc b/client/.prettierrc new file mode 100644 index 00000000000..0244eac5684 --- /dev/null +++ b/client/.prettierrc @@ -0,0 +1,12 @@ +{ + "semi": true, + "bracketSpacing": true, + "arrowParens": "always", + "endOfLine": "lf", + "jsxSingleQuote": true, + "printWidth": 100, + "quoteProps": "consistent", + "singleQuote": true, + "trailingComma": "all", + "useTabs": true +} diff --git a/client/UIKit/hooks/useUIKitHandleAction.tsx b/client/UIKit/hooks/useUIKitHandleAction.tsx index be642ff89c1..276d8655d30 100644 --- a/client/UIKit/hooks/useUIKitHandleAction.tsx +++ b/client/UIKit/hooks/useUIKitHandleAction.tsx @@ -10,15 +10,20 @@ import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; import * as ActionManager from '../../../app/ui-message/client/ActionManager'; import { UiKitPayload, UIKitActionEvent } from '../../../definition/UIKit'; -const useUIKitHandleAction = (state: S): (event: UIKitActionEvent) => Promise => useMutableCallback(async ({ blockId, value, appId, actionId }) => ActionManager.triggerBlockAction({ - container: { - type: UIKitIncomingInteractionContainerType.VIEW, - id: state.viewId || state.appId, - }, - actionId, - appId, - value, - blockId, -})); +const useUIKitHandleAction = ( + state: S, +): ((event: UIKitActionEvent) => Promise) => + useMutableCallback(async ({ blockId, value, appId, actionId }) => + ActionManager.triggerBlockAction({ + container: { + type: UIKitIncomingInteractionContainerType.VIEW, + id: state.viewId || state.appId, + }, + actionId, + appId, + value, + blockId, + }), + ); export { useUIKitHandleAction }; diff --git a/client/UIKit/hooks/useUIKitHandleClose.tsx b/client/UIKit/hooks/useUIKitHandleClose.tsx index 975f895f15b..cd0577c2306 100644 --- a/client/UIKit/hooks/useUIKitHandleClose.tsx +++ b/client/UIKit/hooks/useUIKitHandleClose.tsx @@ -7,29 +7,36 @@ import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; // import { UIKitIncomingInteractionContainerType } from '@rocket.chat/apps-engine/definition/uikit/UIKitIncomingInteractionContainer'; // import { useEndpoint } from '../../contexts/ServerContext'; -import { useToastMessageDispatch } from '../../contexts/ToastMessagesContext'; import * as ActionManager from '../../../app/ui-message/client/ActionManager'; import { UiKitPayload } from '../../../definition/UIKit'; +import { useToastMessageDispatch } from '../../contexts/ToastMessagesContext'; // eslint-disable-next-line @typescript-eslint/no-unused-vars const emptyFn = (_error: any, _result: UIKitInteractionType | void): void => undefined; -const useUIKitHandleClose = (state: S, fn = emptyFn): () => Promise => { +const useUIKitHandleClose = ( + state: S, + fn = emptyFn, +): (() => Promise) => { const dispatchToastMessage = useToastMessageDispatch(); - return useMutableCallback(() => ActionManager.triggerCancel({ - appId: state.appId, - viewId: state.viewId, - view: { - ...state, - id: state.viewId, - // state: groupStateByBlockId(values), - }, - isCleared: true, - }).then((result) => fn(undefined, result)).catch((error) => { - dispatchToastMessage({ type: 'error', message: error }); - fn(error, undefined); - return Promise.reject(error); - })); + return useMutableCallback(() => + ActionManager.triggerCancel({ + appId: state.appId, + viewId: state.viewId, + view: { + ...state, + id: state.viewId, + // state: groupStateByBlockId(values), + }, + isCleared: true, + }) + .then((result) => fn(undefined, result)) + .catch((error) => { + dispatchToastMessage({ type: 'error', message: error }); + fn(error, undefined); + return Promise.reject(error); + }), + ); }; export { useUIKitHandleClose }; diff --git a/client/UIKit/hooks/useUIKitStateManager.tsx b/client/UIKit/hooks/useUIKitStateManager.tsx index 1017af4b61d..c773f18d012 100644 --- a/client/UIKit/hooks/useUIKitStateManager.tsx +++ b/client/UIKit/hooks/useUIKitStateManager.tsx @@ -1,9 +1,8 @@ -import { useEffect, useState } from 'react'; import { useSafely } from '@rocket.chat/fuselage-hooks'; +import { useEffect, useState } from 'react'; -import { isErrorType, UIKitUserInteractionResult, UiKitPayload } from '../../../definition/UIKit'; import * as ActionManager from '../../../app/ui-message/client/ActionManager'; - +import { isErrorType, UIKitUserInteractionResult, UiKitPayload } from '../../../definition/UIKit'; const useUIKitStateManager = (initialState: S): S => { const [state, setState] = useSafely(useState(initialState)); diff --git a/client/adapters.js b/client/adapters.js deleted file mode 100644 index 31980a2227f..00000000000 --- a/client/adapters.js +++ /dev/null @@ -1,7 +0,0 @@ -import { createTemplateForComponent } from './reactAdapters'; - -createTemplateForComponent('MessageActions', () => import('./components/Message/Actions')); -createTemplateForComponent('reactAttachments', () => import('./components/Message/Attachments')); -createTemplateForComponent('ThreadMetric', () => import('./components/Message/Metrics/Thread')); -createTemplateForComponent('DiscussionMetric', () => import('./components/Message/Metrics/Discussion')); -createTemplateForComponent('BroadCastMetric', () => import('./components/Message/Metrics/Broadcast')); diff --git a/client/components/AppRoot.js b/client/components/AppRoot.js deleted file mode 100644 index eaceafdd8f0..00000000000 --- a/client/components/AppRoot.js +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import { useSubscription } from 'use-subscription'; - -import MeteorProvider from '../providers/MeteorProvider'; -import { portalsSubscription } from '../reactAdapters'; -import BannerRegion from '../views/banners/BannerRegion'; -import PortalWrapper from './PortalWrapper'; - -const AppRoot = () => { - const portals = useSubscription(portalsSubscription); - - return - - {portals.map(({ key, portal }) => )} - ; -}; - -export default AppRoot; diff --git a/client/components/AutoComplete.js b/client/components/AutoComplete.js deleted file mode 100644 index d49166ec857..00000000000 --- a/client/components/AutoComplete.js +++ /dev/null @@ -1,25 +0,0 @@ -import React, { useMemo, useState } from 'react'; -import { AutoComplete, Option, Options } from '@rocket.chat/fuselage'; - -import UserAvatar from './avatar/UserAvatar'; -import { useEndpointData } from '../hooks/useEndpointData'; - -const query = (term = '', conditions = {}) => ({ selector: JSON.stringify({ term, conditions }) }); - -const Avatar = ({ value, ...props }) => ; - -export const UserAutoComplete = React.memo((props) => { - const { conditions = {} } = props; - const [filter, setFilter] = useState(''); - // eslint-disable-next-line react-hooks/exhaustive-deps - const { value: data } = useEndpointData('users.autocomplete', useMemo(() => query(filter, conditions), [filter])); - const options = useMemo(() => (data && data.items.map((user) => ({ value: user.username, label: user.name }))) || [], [data]); - return <> {label}} - renderItem={({ value, ...props }) =>