From 35aeeed1cab7875bb622f4c1a33be743ab7e851e Mon Sep 17 00:00:00 2001 From: Yash Rajpal <58601732+yash-rajpal@users.noreply.github.com> Date: Tue, 23 May 2023 01:51:54 +0530 Subject: [PATCH 01/46] fix: Room leader padding always visible (#29303) --- .changeset/late-carrots-think.md | 5 +++++ apps/meteor/client/views/room/components/body/RoomBody.tsx | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 .changeset/late-carrots-think.md diff --git a/.changeset/late-carrots-think.md b/.changeset/late-carrots-think.md new file mode 100644 index 000000000000..4a27a6c1ef77 --- /dev/null +++ b/.changeset/late-carrots-think.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': minor +--- + +fix: Hide roomLeader padding diff --git a/apps/meteor/client/views/room/components/body/RoomBody.tsx b/apps/meteor/client/views/room/components/body/RoomBody.tsx index 40a5199eecda..2859395ac2cc 100644 --- a/apps/meteor/client/views/room/components/body/RoomBody.tsx +++ b/apps/meteor/client/views/room/components/body/RoomBody.tsx @@ -563,7 +563,10 @@ const RoomBody = (): ReactElement => { /> ))} -
+
Date: Mon, 22 May 2023 22:27:58 -0300 Subject: [PATCH 02/46] regression: fix sdk regressions (#29327) * regression: presence structure * regression: fix response.json() being called twice --- apps/meteor/app/notifications/client/lib/Presence.ts | 4 ++-- .../server/modules/notifications/notifications.module.ts | 2 +- packages/api-client/__tests__/2fahandling.spec.ts | 2 +- packages/api-client/src/index.ts | 4 +++- packages/ui-contexts/src/ServerContext/streams.ts | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/meteor/app/notifications/client/lib/Presence.ts b/apps/meteor/app/notifications/client/lib/Presence.ts index 29e0709c0ac9..adeaa4d67f2c 100644 --- a/apps/meteor/app/notifications/client/lib/Presence.ts +++ b/apps/meteor/app/notifications/client/lib/Presence.ts @@ -4,10 +4,10 @@ import { Presence, STATUS_MAP } from '../../../../client/lib/presence'; // TODO implement API on Streamer to be able to listen to all streamed data // this is a hacky way to listen to all streamed data from user-presence Streamer -(Meteor as any).StreamerCentral.on('stream-user-presence', (uid: string, args: unknown) => { +(Meteor as any).StreamerCentral.on('stream-user-presence', (uid: string, ...args: unknown[]) => { if (!Array.isArray(args)) { throw new Error('Presence event must be an array'); } - const [username, status, statusText] = args as [string, number, string | undefined]; + const [username, status, statusText] = args[0] as [string, number, string | undefined]; Presence.notify({ _id: uid, username, status: STATUS_MAP[status], statusText }); }); diff --git a/apps/meteor/server/modules/notifications/notifications.module.ts b/apps/meteor/server/modules/notifications/notifications.module.ts index a9fd5fadd013..46d437f0544a 100644 --- a/apps/meteor/server/modules/notifications/notifications.module.ts +++ b/apps/meteor/server/modules/notifications/notifications.module.ts @@ -535,7 +535,7 @@ export class NotificationsModule { // console.log('notifyUserAndBroadcast', [userId, eventName, ...args]); // } emit(uid, args as any); - return this.streamPresence.emitWithoutBroadcast(uid, ...args); + return this.streamPresence.emitWithoutBroadcast(uid, args); } progressUpdated(progress: { diff --git a/packages/api-client/__tests__/2fahandling.spec.ts b/packages/api-client/__tests__/2fahandling.spec.ts index f4cffc105d55..a53cd8928457 100644 --- a/packages/api-client/__tests__/2fahandling.spec.ts +++ b/packages/api-client/__tests__/2fahandling.spec.ts @@ -71,7 +71,7 @@ test('if the 2fa handler is not provided, it should throw an error', async () => expect(error.status).toBe(400); - const body = error.body && (await JSON.parse(error.body.toString())); + const body = error.json(); expect(body).toMatchObject({ errorType: 'totp-required', diff --git a/packages/api-client/src/index.ts b/packages/api-client/src/index.ts index fbad9807f451..a93cb5942730 100644 --- a/packages/api-client/src/index.ts +++ b/packages/api-client/src/index.ts @@ -234,7 +234,9 @@ export class RestClient implements RestClientInterface { return Promise.reject(response); } - const error = await response.json(); + const clone = response.clone(); + + const error = await clone.json(); if ((isTotpRequiredError(error) || isTotpInvalidError(error)) && hasRequiredTwoFactorMethod(error) && this.twoFactorHandler) { const method2fa = 'details' in error ? error.details.method : 'password'; diff --git a/packages/ui-contexts/src/ServerContext/streams.ts b/packages/ui-contexts/src/ServerContext/streams.ts index 036941a983d5..6165e15708d6 100644 --- a/packages/ui-contexts/src/ServerContext/streams.ts +++ b/packages/ui-contexts/src/ServerContext/streams.ts @@ -297,7 +297,7 @@ export interface StreamerEvents { }, ]; - 'user-presence': [{ key: string; args: [username: string, statusChanged?: 0 | 1 | 2 | 3, statusText?: string] }]; + 'user-presence': [{ key: string; args: [[username: string, statusChanged?: 0 | 1 | 2 | 3, statusText?: string]] }]; // TODO: rename to 'integration-history' 'integrationHistory': [ From 1687bfbe3a6af77614e2c20a0ec9c59a218edc66 Mon Sep 17 00:00:00 2001 From: Debdut Chakraborty Date: Tue, 23 May 2023 18:20:32 +0530 Subject: [PATCH 03/46] fix: unable to create user if Accounts_ManuallyApproveNewUsers is enabled (#29293) --- .changeset/heavy-years-repeat.md | 5 +++++ apps/meteor/app/authentication/server/startup/index.js | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/heavy-years-repeat.md diff --git a/.changeset/heavy-years-repeat.md b/.changeset/heavy-years-repeat.md new file mode 100644 index 000000000000..fc88cd86553b --- /dev/null +++ b/.changeset/heavy-years-repeat.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': patch +--- + +fix: Admins unable to create new users if new users require manual approval diff --git a/apps/meteor/app/authentication/server/startup/index.js b/apps/meteor/app/authentication/server/startup/index.js index f8d39f14b7ab..726518465e9c 100644 --- a/apps/meteor/app/authentication/server/startup/index.js +++ b/apps/meteor/app/authentication/server/startup/index.js @@ -196,7 +196,7 @@ const onCreateUserAsync = async function (options, user = {}) { if (!user.active) { const destinations = []; const usersInRole = await Roles.findUsersInRole('admin'); - await usersInRole.toArray().forEach((adminUser) => { + await usersInRole.forEach((adminUser) => { if (Array.isArray(adminUser.emails)) { adminUser.emails.forEach((email) => { destinations.push(`${adminUser.name}<${email.address}>`); From f8cd53bc7e89ab45c8963d65c99c96d87756d91a Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Tue, 23 May 2023 11:03:58 -0600 Subject: [PATCH 04/46] fix: Add missing awaits to .count() calls (#29323) --- .changeset/quiet-rules-swim.md | 5 +++++ apps/meteor/app/importer-pending-avatars/server/importer.js | 2 +- apps/meteor/app/livechat/client/startup/notifyUnreadRooms.js | 2 +- apps/meteor/app/livechat/server/lib/Helper.js | 2 +- apps/meteor/app/livechat/server/lib/Livechat.js | 2 +- apps/meteor/app/slashcommands-inviteall/server/server.ts | 4 ++-- 6 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 .changeset/quiet-rules-swim.md diff --git a/.changeset/quiet-rules-swim.md b/.changeset/quiet-rules-swim.md new file mode 100644 index 000000000000..005517c1d695 --- /dev/null +++ b/.changeset/quiet-rules-swim.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +fix: Add missing awaits to .count() calls diff --git a/apps/meteor/app/importer-pending-avatars/server/importer.js b/apps/meteor/app/importer-pending-avatars/server/importer.js index b85792a406c1..912d253e808c 100644 --- a/apps/meteor/app/importer-pending-avatars/server/importer.js +++ b/apps/meteor/app/importer-pending-avatars/server/importer.js @@ -9,7 +9,7 @@ export class PendingAvatarImporter extends Base { await super.updateProgress(ProgressStep.PREPARING_STARTED); const users = await Users.findAllUsersWithPendingAvatar(); - const fileCount = users.count(); + const fileCount = await users.count(); if (fileCount === 0) { await super.updateProgress(ProgressStep.DONE); diff --git a/apps/meteor/app/livechat/client/startup/notifyUnreadRooms.js b/apps/meteor/app/livechat/client/startup/notifyUnreadRooms.js index 51af1a47aa38..f730925f50d9 100644 --- a/apps/meteor/app/livechat/client/startup/notifyUnreadRooms.js +++ b/apps/meteor/app/livechat/client/startup/notifyUnreadRooms.js @@ -16,7 +16,7 @@ Meteor.startup(() => { return; } - const subs = Subscriptions.find({ t: 'l', ls: { $exists: 0 }, open: true }).count(); + const subs = await Subscriptions.find({ t: 'l', ls: { $exists: 0 }, open: true }).count(); if (subs === 0) { audio && audio.pause(); return; diff --git a/apps/meteor/app/livechat/server/lib/Helper.js b/apps/meteor/app/livechat/server/lib/Helper.js index e862ec350760..eb57dcf8e697 100644 --- a/apps/meteor/app/livechat/server/lib/Helper.js +++ b/apps/meteor/app/livechat/server/lib/Helper.js @@ -299,7 +299,7 @@ export const dispatchInquiryQueued = async (inquiry, agent) => { return; } - logger.debug(`Notifying ${onlineAgents.count()} agents of new inquiry`); + logger.debug(`Notifying ${await onlineAgents.count()} agents of new inquiry`); const notificationUserName = v && (v.name || v.username); for await (let agent of onlineAgents) { diff --git a/apps/meteor/app/livechat/server/lib/Livechat.js b/apps/meteor/app/livechat/server/lib/Livechat.js index ae39d8a21d87..fca1813820da 100644 --- a/apps/meteor/app/livechat/server/lib/Livechat.js +++ b/apps/meteor/app/livechat/server/lib/Livechat.js @@ -78,7 +78,7 @@ export const Livechat = { if (settings.get('Livechat_assign_new_conversation_to_bot')) { Livechat.logger.debug(`Fetching online bot agents for department ${department}`); const botAgents = await Livechat.getBotAgents(department); - const onlineBots = botAgents.count(); + const onlineBots = await botAgents.count(); Livechat.logger.debug(`Found ${onlineBots} online`); if (onlineBots > 0) { return true; diff --git a/apps/meteor/app/slashcommands-inviteall/server/server.ts b/apps/meteor/app/slashcommands-inviteall/server/server.ts index 8478bbfba003..cd5ed9dc4932 100644 --- a/apps/meteor/app/slashcommands-inviteall/server/server.ts +++ b/apps/meteor/app/slashcommands-inviteall/server/server.ts @@ -57,11 +57,11 @@ function inviteAll(type: T): SlashCommand['callback'] { }); try { - const APIsettings = settings.get('API_User_Limit'); + const APIsettings = settings.get('API_User_Limit'); if (!APIsettings) { return; } - if (cursor.count() > APIsettings) { + if ((await cursor.count()) > APIsettings) { throw new Meteor.Error('error-user-limit-exceeded', 'User Limit Exceeded', { method: 'addAllToRoom', }); From cc68894674070308f4fec02444d677e1f9261871 Mon Sep 17 00:00:00 2001 From: csuadev <72958726+csuadev@users.noreply.github.com> Date: Tue, 23 May 2023 14:57:34 -0500 Subject: [PATCH 05/46] chore: hide releases tab for private apps on marketplace (#29129) --- .../marketplace/AppDetailsPage/AppDetailsPage.tsx | 6 +++--- .../AppDetailsPage/AppDetailsPageTabs.tsx | 14 +++----------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/apps/meteor/client/views/marketplace/AppDetailsPage/AppDetailsPage.tsx b/apps/meteor/client/views/marketplace/AppDetailsPage/AppDetailsPage.tsx index 4272db0522d9..d1688b22c6ab 100644 --- a/apps/meteor/client/views/marketplace/AppDetailsPage/AppDetailsPage.tsx +++ b/apps/meteor/client/views/marketplace/AppDetailsPage/AppDetailsPage.tsx @@ -53,7 +53,8 @@ const AppDetailsPage = ({ id }: { id: App['id'] }): ReactElement => { context && router.push({ context, page: 'list' }); }); - const { installed, settings, privacyPolicySummary, permissions, tosLink, privacyLink, marketplace, name } = appData || {}; + const { installed, settings, privacyPolicySummary, permissions, tosLink, privacyLink, name } = appData || {}; + const isSecurityVisible = Boolean(privacyPolicySummary || permissions || tosLink || privacyLink); const saveAppSettings = useCallback(async () => { @@ -94,12 +95,11 @@ const AppDetailsPage = ({ id }: { id: App['id'] }): ReactElement => { <> {Boolean(!tab || tab === 'details') && } {tab === 'requests' && } diff --git a/apps/meteor/client/views/marketplace/AppDetailsPage/AppDetailsPageTabs.tsx b/apps/meteor/client/views/marketplace/AppDetailsPage/AppDetailsPageTabs.tsx index ff3ddef243a0..d93af7b44d19 100644 --- a/apps/meteor/client/views/marketplace/AppDetailsPage/AppDetailsPageTabs.tsx +++ b/apps/meteor/client/views/marketplace/AppDetailsPage/AppDetailsPageTabs.tsx @@ -6,22 +6,14 @@ import React from 'react'; import type { ISettings } from '../../../../ee/client/apps/@types/IOrchestrator'; type AppDetailsPageTabsProps = { + context: string; installed: boolean | undefined; isSecurityVisible: boolean; - marketplace: unknown; settings: ISettings | undefined; tab: string | undefined; - context: string; }; -const AppDetailsPageTabs = ({ - installed, - isSecurityVisible, - marketplace, - settings, - tab, - context, -}: AppDetailsPageTabsProps): ReactElement => { +const AppDetailsPageTabs = ({ context, installed, isSecurityVisible, settings, tab }: AppDetailsPageTabsProps): ReactElement => { const t = useTranslation(); const isAdminUser = usePermission('manage-apps'); @@ -51,7 +43,7 @@ const AppDetailsPageTabs = ({ {t('Security')} )} - {marketplace !== false && ( + {context !== 'private' && ( handleTabClick('releases')} selected={tab === 'releases'}> {t('Releases')} From 09075132385b32caafe29d038c5d856f021cd3bd Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Tue, 23 May 2023 16:07:30 -0600 Subject: [PATCH 06/46] test: Fix Omnichannel Webhooks tests (#29344) --- .github/workflows/ci-test-e2e.yml | 1 + apps/meteor/tests/end-to-end/api/livechat/06-integrations.ts | 1 + docker-compose-ci.yml | 1 - 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-test-e2e.yml b/.github/workflows/ci-test-e2e.yml index 2fca0c3e36ac..a27915154277 100644 --- a/.github/workflows/ci-test-e2e.yml +++ b/.github/workflows/ci-test-e2e.yml @@ -214,6 +214,7 @@ jobs: if: inputs.type == 'api' working-directory: ./apps/meteor env: + WEBHOOK_TEST_URL: 'http://host.docker.internal:10000' IS_EE: ${{ inputs.release == 'ee' && 'true' || '' }} run: | for i in $(seq 1 2); do diff --git a/apps/meteor/tests/end-to-end/api/livechat/06-integrations.ts b/apps/meteor/tests/end-to-end/api/livechat/06-integrations.ts index f5a88fd69ca2..8a90822406da 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/06-integrations.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/06-integrations.ts @@ -123,6 +123,7 @@ describe('LIVECHAT - Integrations', function () { describe('Livechat - Webhooks', () => { const webhookUrl = process.env.WEBHOOK_TEST_URL || 'https://httpbin.org'; + describe('livechat/webhook.test', () => { it('should fail when user doesnt have view-livechat-webhooks permission', async () => { await updatePermission('view-livechat-webhooks', []); diff --git a/docker-compose-ci.yml b/docker-compose-ci.yml index a47ca7db662c..ab54ed2d57d2 100644 --- a/docker-compose-ci.yml +++ b/docker-compose-ci.yml @@ -15,7 +15,6 @@ services: - 'TRANSPORTER=${TRANSPORTER}' - MOLECULER_LOG_LEVEL=info - 'ROCKETCHAT_LICENSE=${ENTERPRISE_LICENSE}' - - 'WEBHOOK_TEST_URL=host.docker.internal:10000' extra_hosts: - 'host.docker.internal:host-gateway' depends_on: From 89e2c266255025cc69781c23504648261a48dd04 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Tue, 23 May 2023 22:00:08 -0300 Subject: [PATCH 07/46] regression: Fix secondary presence streamer (#29340) --- apps/meteor/app/notifications/client/lib/Presence.ts | 10 +++++++--- apps/meteor/app/notifications/server/lib/Presence.ts | 5 +++-- .../modules/notifications/notifications.module.ts | 5 +---- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/apps/meteor/app/notifications/client/lib/Presence.ts b/apps/meteor/app/notifications/client/lib/Presence.ts index adeaa4d67f2c..0c04a164d936 100644 --- a/apps/meteor/app/notifications/client/lib/Presence.ts +++ b/apps/meteor/app/notifications/client/lib/Presence.ts @@ -1,13 +1,17 @@ import { Meteor } from 'meteor/meteor'; +import type { StreamerEvents } from '@rocket.chat/ui-contexts'; import { Presence, STATUS_MAP } from '../../../../client/lib/presence'; // TODO implement API on Streamer to be able to listen to all streamed data // this is a hacky way to listen to all streamed data from user-presence Streamer -(Meteor as any).StreamerCentral.on('stream-user-presence', (uid: string, ...args: unknown[]) => { + +new Meteor.Streamer('user-presence'); + +(Meteor as any).StreamerCentral.on('stream-user-presence', (uid: string, ...args: StreamerEvents['user-presence'][number]['args']) => { if (!Array.isArray(args)) { throw new Error('Presence event must be an array'); } - const [username, status, statusText] = args[0] as [string, number, string | undefined]; - Presence.notify({ _id: uid, username, status: STATUS_MAP[status], statusText }); + const [[username, status, statusText]] = args; + Presence.notify({ _id: uid, username, status: STATUS_MAP[status ?? 0], statusText }); }); diff --git a/apps/meteor/app/notifications/server/lib/Presence.ts b/apps/meteor/app/notifications/server/lib/Presence.ts index 304e533d599a..5f258c05f998 100644 --- a/apps/meteor/app/notifications/server/lib/Presence.ts +++ b/apps/meteor/app/notifications/server/lib/Presence.ts @@ -1,6 +1,7 @@ import { Emitter } from '@rocket.chat/emitter'; import type { IPublication, IStreamerConstructor, Connection, IStreamer } from 'meteor/rocketchat:streamer'; import type { IUser } from '@rocket.chat/core-typings'; +import type { StreamerEvents } from '@rocket.chat/ui-contexts'; type UserPresenceStreamProps = { added: IUser['_id'][]; @@ -9,7 +10,7 @@ type UserPresenceStreamProps = { type UserPresenceStreamArgs = { uid: string; - args: unknown; + args: StreamerEvents['user-presence'][number]['args']; }; const e = new Emitter<{ @@ -97,6 +98,6 @@ export class StreamPresence { } } -export const emit = (uid: string, args: UserPresenceStreamArgs): void => { +export const emit = (uid: string, args: UserPresenceStreamArgs['args']): void => { e.emit(uid, { uid, args }); }; diff --git a/apps/meteor/server/modules/notifications/notifications.module.ts b/apps/meteor/server/modules/notifications/notifications.module.ts index 46d437f0544a..0b82792ee819 100644 --- a/apps/meteor/server/modules/notifications/notifications.module.ts +++ b/apps/meteor/server/modules/notifications/notifications.module.ts @@ -531,10 +531,7 @@ export class NotificationsModule { } sendPresence(uid: string, ...args: [username: string, statusChanged: 0 | 1 | 2 | 3, statusText: string | undefined]): void { - // if (this.debug === true) { - // console.log('notifyUserAndBroadcast', [userId, eventName, ...args]); - // } - emit(uid, args as any); + emit(uid, [args]); return this.streamPresence.emitWithoutBroadcast(uid, args); } From 7e00009ddb2d23995eacf5b176b0ebc8007e4bb6 Mon Sep 17 00:00:00 2001 From: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com> Date: Wed, 24 May 2023 10:15:40 +0530 Subject: [PATCH 08/46] fix: Application crashes when clicking on Analytics option in Omnichannel view page (#29286) Co-authored-by: Yash Rajpal <58601732+yash-rajpal@users.noreply.github.com> --- .changeset/wild-lizards-guess.md | 5 +++++ apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/wild-lizards-guess.md diff --git a/.changeset/wild-lizards-guess.md b/.changeset/wild-lizards-guess.md new file mode 100644 index 000000000000..4a7b45515df7 --- /dev/null +++ b/.changeset/wild-lizards-guess.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': minor +--- + +fix: Analytics page crash diff --git a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json index 3873e3448fc3..f2e5c8da4769 100644 --- a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json @@ -17,7 +17,7 @@ "@username": "@username", "@username_message": "@username ", "#channel": "#channel", - "%_of_conversations": "% of Conversations", + "%_of_conversations": "%% of Conversations", "0_Errors_Only": "0 - Errors Only", "1_Errors_and_Information": "1 - Errors and Information", "2_Erros_Information_and_Debug": "2 - Errors, Information and Debug", From c95cda43e69b931cb2c902f9cd031ac064930f6a Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Wed, 24 May 2023 11:03:07 -0300 Subject: [PATCH 09/46] fix: getActiveLocalUserCount query (#29349) --- .changeset/cold-years-beg.md | 5 +++++ apps/meteor/server/models/raw/Users.js | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .changeset/cold-years-beg.md diff --git a/.changeset/cold-years-beg.md b/.changeset/cold-years-beg.md new file mode 100644 index 000000000000..4c4cf5c03568 --- /dev/null +++ b/.changeset/cold-years-beg.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +fix: getActiveLocalUserCount query always returning 0 diff --git a/apps/meteor/server/models/raw/Users.js b/apps/meteor/server/models/raw/Users.js index 066fad73fc9d..2e31696eda52 100644 --- a/apps/meteor/server/models/raw/Users.js +++ b/apps/meteor/server/models/raw/Users.js @@ -2819,7 +2819,11 @@ export class UsersRaw extends BaseRaw { // here getActiveLocalUserCount() { - return this.col.countDocuments({ active: true, federated: false, isRemote: false }); + return Promise.all([ + this.col.countDocuments({ active: true }), + this.col.countDocuments({ federated: true }), + this.col.countDocuments({ isRemote: true }), + ]).then((results) => results.reduce((a, b) => a - b)); } getActiveLocalGuestCount(idExceptions = []) { From 58359b054e1fb9eb4c245d9e4fb9fbb5f2f165f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Jaeger=20Foresti?= <60678893+juliajforesti@users.noreply.github.com> Date: Wed, 24 May 2023 16:21:08 +0100 Subject: [PATCH 10/46] chore: add `badge-level-0` token (#29326) --- ee/packages/ui-theming/src/palette.ts | 1 + ee/packages/ui-theming/src/paletteDark.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/ee/packages/ui-theming/src/palette.ts b/ee/packages/ui-theming/src/palette.ts index 9623db5ea604..2405ecb2c6d7 100644 --- a/ee/packages/ui-theming/src/palette.ts +++ b/ee/packages/ui-theming/src/palette.ts @@ -87,6 +87,7 @@ export const palette = [ category: 'Badge', description: 'Badge Background', list: [ + { name: 'badge-background-level-0', token: '', color: '#E4E7EA' }, { name: 'badge-background-level-1', token: 'N700', color: '#6C727A' }, { name: 'badge-background-level-2', token: '', color: '#1D74F5' }, { name: 'badge-background-level-3', token: '', color: '#F38C39' }, diff --git a/ee/packages/ui-theming/src/paletteDark.ts b/ee/packages/ui-theming/src/paletteDark.ts index 9e5ef724b1c0..d68881a2a0a5 100644 --- a/ee/packages/ui-theming/src/paletteDark.ts +++ b/ee/packages/ui-theming/src/paletteDark.ts @@ -87,6 +87,7 @@ export const palette = [ category: 'Badge', description: 'Badge Background', list: [ + { name: 'badge-background-level-0', token: '', color: '#2F343D' }, { name: 'badge-background-level-1', token: '', color: '#484C51' }, { name: 'badge-background-level-2', token: '', color: '#3070CF' }, { name: 'badge-background-level-3', token: '', color: '#A9642D' }, From dae9c8dd9fdaa6f26811f5b25ef26632f7af25e9 Mon Sep 17 00:00:00 2001 From: Tiago Evangelista Pinto Date: Wed, 24 May 2023 12:55:59 -0300 Subject: [PATCH 11/46] feat: Bring `uikit-playground` package to the monorepo (#29339) Co-authored-by: Guilherme Gazzo <5263975+ggazzo@users.noreply.github.com> --- packages/uikit-playground/.eslintignore | 18 + packages/uikit-playground/.eslintrc.cjs | 14 + packages/uikit-playground/.gitignore | 24 + packages/uikit-playground/index.html | 13 + packages/uikit-playground/package.json | 54 + packages/uikit-playground/public/vite.svg | 1 + packages/uikit-playground/src/App.css | 39 + packages/uikit-playground/src/App.tsx | 18 + .../CodeEditor/Extensions/HighlightStyle.ts | 14 + .../CodeEditor/Extensions/basicSetup.ts | 59 + .../Components/CodeEditor/Extensions/index.ts | 10 + .../Components/CodeEditor/Extensions/lint.ts | 5 + .../Components/CodeEditor/Extensions/theme.ts | 41 + .../src/Components/CodeEditor/index.tsx | 75 ++ .../ComponentSideBar/ScrollableSideBar.tsx | 24 + .../Components/ComponentSideBar/SideBar.tsx | 46 + .../Components/ComponentSideBar/SliderBtn.tsx | 116 ++ .../src/Components/ComponentSideBar/index.tsx | 1 + .../Components/Draggable/DraggableList.tsx | 51 + .../Draggable/DraggableListItem.tsx | 34 + .../src/Components/DropDown/DropDown.tsx | 34 + .../src/Components/DropDown/Items.tsx | 66 + .../src/Components/DropDown/ItemsIcon.tsx | 28 + .../src/Components/DropDown/index.tsx | 1 + .../src/Components/DropDown/itemsStyle.ts | 45 + .../src/Components/DropDown/types.ts | 16 + .../NavBar/BurgerIcon/BurgerIcon.tsx | 25 + .../src/Components/NavBar/BurgerIcon/Line.tsx | 52 + .../Components/NavBar/BurgerIcon/Wrapper.tsx | 24 + .../Components/NavBar/BurgerIcon/index.tsx | 1 + .../src/Components/NavBar/Divider.tsx | 6 + .../src/Components/NavBar/Logo.tsx | 18 + .../src/Components/NavBar/NavBar.tsx | 31 + .../src/Components/NavBar/RightNavBtn.tsx | 25 + .../src/Components/NavBar/index.tsx | 1 + .../Components/Preview/Display/Display.tsx | 18 + .../RenderPayload/DeleteElementBtn.tsx | 43 + .../Display/RenderPayload/ElementWrapper.tsx | 40 + .../Display/RenderPayload/RenderPayload.tsx | 35 + .../Preview/Display/RenderPayload/intex.ts | 1 + .../Preview/Display/Surface/BannerSurface.tsx | 12 + .../Display/Surface/MessageSurface.tsx | 49 + .../Preview/Display/Surface/ModalSurface.tsx | 35 + .../Preview/Display/Surface/Reorder.ts | 11 + .../Preview/Display/Surface/Surface.tsx | 50 + .../Preview/Display/Surface/index.ts | 1 + .../src/Components/Preview/Display/index.ts | 1 + .../src/Components/Preview/Editor/Editor.tsx | 24 + .../src/Components/Preview/Editor/index.tsx | 1 + .../Components/Preview/NavPanel/NavPanel.tsx | 57 + .../Components/Preview/NavPanel/PanelBtn.tsx | 38 + .../Components/Preview/NavPanel/TabChange.tsx | 37 + .../src/Components/Preview/NavPanel/index.tsx | 1 + .../src/Components/Preview/Preview.tsx | 40 + .../SplitPlaneContainer.tsx | 47 + .../Preview/SplitPlaneContainer/index.ts | 1 + .../SplitPlaneContainer/splitPlane.css | 53 + .../src/Components/Preview/Wrapper.tsx | 46 + .../src/Components/Preview/index.tsx | 1 + .../SurfaceSelect/SurfaceSelect.tsx | 26 + .../src/Components/SurfaceSelect/index.ts | 1 + .../src/Components/SurfaceSelect/options.ts | 9 + .../src/Components/hooks/useCodeMirror.ts | 80 ++ .../src/Components/navMenu/Menu/MenuItem.tsx | 35 + .../src/Components/navMenu/Menu/Wrapper.tsx | 19 + .../src/Components/navMenu/Menu/index.tsx | 48 + .../src/Components/navMenu/NavMenu.tsx | 48 + .../src/Components/navMenu/index.ts | 1 + .../src/Components/utils/codePrettier.ts | 14 + .../src/Context/action/docAction.ts | 11 + .../src/Context/action/index.ts | 7 + .../src/Context/action/isMobileAction.ts | 9 + .../src/Context/action/isTabletAction.ts | 9 + .../src/Context/action/navMenuToggleAction.ts | 9 + .../src/Context/action/sidebarToggleAction.ts | 9 + .../src/Context/action/surfaceAction.ts | 9 + .../src/Context/action/tabsToggleAction.ts | 9 + .../src/Context/createCtx.tsx | 23 + .../uikit-playground/src/Context/index.tsx | 8 + .../src/Context/initialState.ts | 26 + .../uikit-playground/src/Context/reducer.ts | 35 + .../uikit-playground/src/Pages/Playground.tsx | 51 + .../src/Payload/BlocksTree.ts | 268 ++++ .../src/Payload/action/button.ts | 80 ++ .../src/Payload/action/datePicker.ts | 21 + .../src/Payload/action/image.ts | 10 + .../src/Payload/action/index.ts | 13 + .../src/Payload/action/input.ts | 37 + .../src/Payload/action/linearScale.ts | 18 + .../src/Payload/action/menu.ts | 33 + .../src/Payload/action/staticSelect.ts | 75 ++ .../src/Payload/context/index.ts | 61 + .../src/Payload/divider/index.ts | 7 + .../src/Payload/image/index.ts | 22 + .../src/Payload/input/datePicker.ts | 24 + .../src/Payload/input/index.ts | 7 + .../src/Payload/input/input.ts | 49 + .../src/Payload/input/linearScale.ts | 21 + .../src/Payload/input/staticSelect.ts | 81 ++ .../src/Payload/preview/index.ts | 121 ++ .../src/Payload/section/button.ts | 88 ++ .../src/Payload/section/datePicker.ts | 23 + .../src/Payload/section/image.ts | 16 + .../src/Payload/section/index.ts | 9 + .../src/Payload/section/menu.ts | 59 + .../src/Payload/section/text.ts | 55 + .../uikit-playground/src/cssVariables.css | 14 + .../src/hooks/useCodeMirror.ts | 80 ++ packages/uikit-playground/src/index.css | 27 + packages/uikit-playground/src/logo.svg | 7 + packages/uikit-playground/src/main.tsx | 16 + packages/uikit-playground/src/module.d.ts | 7 + .../src/utils/codePrettier.ts | 14 + packages/uikit-playground/src/vite-env.d.ts | 1 + packages/uikit-playground/tsconfig.json | 25 + packages/uikit-playground/vite.config.ts | 15 + yarn.lock | 1157 ++++++++++++++++- 117 files changed, 4713 insertions(+), 16 deletions(-) create mode 100644 packages/uikit-playground/.eslintignore create mode 100644 packages/uikit-playground/.eslintrc.cjs create mode 100644 packages/uikit-playground/.gitignore create mode 100644 packages/uikit-playground/index.html create mode 100644 packages/uikit-playground/package.json create mode 100644 packages/uikit-playground/public/vite.svg create mode 100644 packages/uikit-playground/src/App.css create mode 100644 packages/uikit-playground/src/App.tsx create mode 100644 packages/uikit-playground/src/Components/CodeEditor/Extensions/HighlightStyle.ts create mode 100644 packages/uikit-playground/src/Components/CodeEditor/Extensions/basicSetup.ts create mode 100644 packages/uikit-playground/src/Components/CodeEditor/Extensions/index.ts create mode 100644 packages/uikit-playground/src/Components/CodeEditor/Extensions/lint.ts create mode 100644 packages/uikit-playground/src/Components/CodeEditor/Extensions/theme.ts create mode 100644 packages/uikit-playground/src/Components/CodeEditor/index.tsx create mode 100644 packages/uikit-playground/src/Components/ComponentSideBar/ScrollableSideBar.tsx create mode 100644 packages/uikit-playground/src/Components/ComponentSideBar/SideBar.tsx create mode 100644 packages/uikit-playground/src/Components/ComponentSideBar/SliderBtn.tsx create mode 100644 packages/uikit-playground/src/Components/ComponentSideBar/index.tsx create mode 100644 packages/uikit-playground/src/Components/Draggable/DraggableList.tsx create mode 100644 packages/uikit-playground/src/Components/Draggable/DraggableListItem.tsx create mode 100644 packages/uikit-playground/src/Components/DropDown/DropDown.tsx create mode 100644 packages/uikit-playground/src/Components/DropDown/Items.tsx create mode 100644 packages/uikit-playground/src/Components/DropDown/ItemsIcon.tsx create mode 100644 packages/uikit-playground/src/Components/DropDown/index.tsx create mode 100644 packages/uikit-playground/src/Components/DropDown/itemsStyle.ts create mode 100644 packages/uikit-playground/src/Components/DropDown/types.ts create mode 100644 packages/uikit-playground/src/Components/NavBar/BurgerIcon/BurgerIcon.tsx create mode 100644 packages/uikit-playground/src/Components/NavBar/BurgerIcon/Line.tsx create mode 100644 packages/uikit-playground/src/Components/NavBar/BurgerIcon/Wrapper.tsx create mode 100644 packages/uikit-playground/src/Components/NavBar/BurgerIcon/index.tsx create mode 100644 packages/uikit-playground/src/Components/NavBar/Divider.tsx create mode 100644 packages/uikit-playground/src/Components/NavBar/Logo.tsx create mode 100644 packages/uikit-playground/src/Components/NavBar/NavBar.tsx create mode 100644 packages/uikit-playground/src/Components/NavBar/RightNavBtn.tsx create mode 100644 packages/uikit-playground/src/Components/NavBar/index.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/Display/Display.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/Display/RenderPayload/DeleteElementBtn.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/Display/RenderPayload/ElementWrapper.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/Display/RenderPayload/RenderPayload.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/Display/RenderPayload/intex.ts create mode 100644 packages/uikit-playground/src/Components/Preview/Display/Surface/BannerSurface.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/Display/Surface/MessageSurface.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/Display/Surface/ModalSurface.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/Display/Surface/Reorder.ts create mode 100644 packages/uikit-playground/src/Components/Preview/Display/Surface/Surface.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/Display/Surface/index.ts create mode 100644 packages/uikit-playground/src/Components/Preview/Display/index.ts create mode 100644 packages/uikit-playground/src/Components/Preview/Editor/Editor.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/Editor/index.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/NavPanel/NavPanel.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/NavPanel/PanelBtn.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/NavPanel/TabChange.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/NavPanel/index.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/Preview.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/SplitPlaneContainer/SplitPlaneContainer.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/SplitPlaneContainer/index.ts create mode 100644 packages/uikit-playground/src/Components/Preview/SplitPlaneContainer/splitPlane.css create mode 100644 packages/uikit-playground/src/Components/Preview/Wrapper.tsx create mode 100644 packages/uikit-playground/src/Components/Preview/index.tsx create mode 100644 packages/uikit-playground/src/Components/SurfaceSelect/SurfaceSelect.tsx create mode 100644 packages/uikit-playground/src/Components/SurfaceSelect/index.ts create mode 100644 packages/uikit-playground/src/Components/SurfaceSelect/options.ts create mode 100644 packages/uikit-playground/src/Components/hooks/useCodeMirror.ts create mode 100644 packages/uikit-playground/src/Components/navMenu/Menu/MenuItem.tsx create mode 100644 packages/uikit-playground/src/Components/navMenu/Menu/Wrapper.tsx create mode 100644 packages/uikit-playground/src/Components/navMenu/Menu/index.tsx create mode 100644 packages/uikit-playground/src/Components/navMenu/NavMenu.tsx create mode 100644 packages/uikit-playground/src/Components/navMenu/index.ts create mode 100644 packages/uikit-playground/src/Components/utils/codePrettier.ts create mode 100644 packages/uikit-playground/src/Context/action/docAction.ts create mode 100644 packages/uikit-playground/src/Context/action/index.ts create mode 100644 packages/uikit-playground/src/Context/action/isMobileAction.ts create mode 100644 packages/uikit-playground/src/Context/action/isTabletAction.ts create mode 100644 packages/uikit-playground/src/Context/action/navMenuToggleAction.ts create mode 100644 packages/uikit-playground/src/Context/action/sidebarToggleAction.ts create mode 100644 packages/uikit-playground/src/Context/action/surfaceAction.ts create mode 100644 packages/uikit-playground/src/Context/action/tabsToggleAction.ts create mode 100644 packages/uikit-playground/src/Context/createCtx.tsx create mode 100644 packages/uikit-playground/src/Context/index.tsx create mode 100644 packages/uikit-playground/src/Context/initialState.ts create mode 100644 packages/uikit-playground/src/Context/reducer.ts create mode 100644 packages/uikit-playground/src/Pages/Playground.tsx create mode 100644 packages/uikit-playground/src/Payload/BlocksTree.ts create mode 100644 packages/uikit-playground/src/Payload/action/button.ts create mode 100644 packages/uikit-playground/src/Payload/action/datePicker.ts create mode 100644 packages/uikit-playground/src/Payload/action/image.ts create mode 100644 packages/uikit-playground/src/Payload/action/index.ts create mode 100644 packages/uikit-playground/src/Payload/action/input.ts create mode 100644 packages/uikit-playground/src/Payload/action/linearScale.ts create mode 100644 packages/uikit-playground/src/Payload/action/menu.ts create mode 100644 packages/uikit-playground/src/Payload/action/staticSelect.ts create mode 100644 packages/uikit-playground/src/Payload/context/index.ts create mode 100644 packages/uikit-playground/src/Payload/divider/index.ts create mode 100644 packages/uikit-playground/src/Payload/image/index.ts create mode 100644 packages/uikit-playground/src/Payload/input/datePicker.ts create mode 100644 packages/uikit-playground/src/Payload/input/index.ts create mode 100644 packages/uikit-playground/src/Payload/input/input.ts create mode 100644 packages/uikit-playground/src/Payload/input/linearScale.ts create mode 100644 packages/uikit-playground/src/Payload/input/staticSelect.ts create mode 100644 packages/uikit-playground/src/Payload/preview/index.ts create mode 100644 packages/uikit-playground/src/Payload/section/button.ts create mode 100644 packages/uikit-playground/src/Payload/section/datePicker.ts create mode 100644 packages/uikit-playground/src/Payload/section/image.ts create mode 100644 packages/uikit-playground/src/Payload/section/index.ts create mode 100644 packages/uikit-playground/src/Payload/section/menu.ts create mode 100644 packages/uikit-playground/src/Payload/section/text.ts create mode 100644 packages/uikit-playground/src/cssVariables.css create mode 100644 packages/uikit-playground/src/hooks/useCodeMirror.ts create mode 100644 packages/uikit-playground/src/index.css create mode 100644 packages/uikit-playground/src/logo.svg create mode 100644 packages/uikit-playground/src/main.tsx create mode 100644 packages/uikit-playground/src/module.d.ts create mode 100644 packages/uikit-playground/src/utils/codePrettier.ts create mode 100644 packages/uikit-playground/src/vite-env.d.ts create mode 100644 packages/uikit-playground/tsconfig.json create mode 100644 packages/uikit-playground/vite.config.ts diff --git a/packages/uikit-playground/.eslintignore b/packages/uikit-playground/.eslintignore new file mode 100644 index 000000000000..8a42e7e798be --- /dev/null +++ b/packages/uikit-playground/.eslintignore @@ -0,0 +1,18 @@ +/dist +/build +/node_modules +/storybook-static +!/.jest +!/.storybook +/.storybook/jest-results.json + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/packages/uikit-playground/.eslintrc.cjs b/packages/uikit-playground/.eslintrc.cjs new file mode 100644 index 000000000000..4020bcbf409d --- /dev/null +++ b/packages/uikit-playground/.eslintrc.cjs @@ -0,0 +1,14 @@ +module.exports = { + env: { browser: true, es2020: true }, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:react-hooks/recommended', + ], + parser: '@typescript-eslint/parser', + parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, + plugins: ['react-refresh'], + rules: { + 'react-refresh/only-export-components': 'warn', + }, +} diff --git a/packages/uikit-playground/.gitignore b/packages/uikit-playground/.gitignore new file mode 100644 index 000000000000..a547bf36d8d1 --- /dev/null +++ b/packages/uikit-playground/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/packages/uikit-playground/index.html b/packages/uikit-playground/index.html new file mode 100644 index 000000000000..7b1100bf1387 --- /dev/null +++ b/packages/uikit-playground/index.html @@ -0,0 +1,13 @@ + + + + + + + UiKit-Playground + + +
+ + + diff --git a/packages/uikit-playground/package.json b/packages/uikit-playground/package.json new file mode 100644 index 000000000000..d07effed2a73 --- /dev/null +++ b/packages/uikit-playground/package.json @@ -0,0 +1,54 @@ +{ + "name": "@rocket.chat/uikit-playground", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview" + }, + "dependencies": { + "@codemirror/lang-javascript": "^6.1.8", + "@codemirror/lang-json": "^6.0.1", + "@codemirror/tooltip": "^0.19.16", + "@lezer/highlight": "^1.1.4", + "@rocket.chat/css-in-js": "^0.31.12", + "@rocket.chat/fuselage": "next", + "@rocket.chat/fuselage-hooks": "next", + "@rocket.chat/fuselage-polyfills": "next", + "@rocket.chat/fuselage-tokens": "next", + "@rocket.chat/fuselage-ui-kit": "workspace:~", + "@rocket.chat/icons": "next", + "@rocket.chat/logo": "next", + "@rocket.chat/styled": "next", + "@rocket.chat/ui-contexts": "workspace:~", + "codemirror": "^6.0.1", + "eslint4b-prebuilt": "^6.7.2", + "react": "^17.0.2", + "react-beautiful-dnd": "^13.1.1", + "react-dom": "^17.0.2", + "react-router-dom": "^6.11.2", + "react-split-pane": "^0.1.92", + "react-virtuoso": "^4.3.7", + "use-subscription": "^1.8.0" + }, + "devDependencies": { + "@types/react": "^17.0.57", + "@types/react-beautiful-dnd": "^13", + "@types/react-dom": "^17.0.19", + "@types/use-subscription": "^1", + "@typescript-eslint/eslint-plugin": "^5.57.1", + "@typescript-eslint/parser": "^5.57.1", + "@vitejs/plugin-react": "^4.0.0", + "eslint": "^8.38.0", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.3.4", + "typescript": "^5.0.2", + "vite": "^4.3.2" + }, + "volta": { + "extends": "../../package.json" + } +} diff --git a/packages/uikit-playground/public/vite.svg b/packages/uikit-playground/public/vite.svg new file mode 100644 index 000000000000..e7b8dfb1b2a6 --- /dev/null +++ b/packages/uikit-playground/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/uikit-playground/src/App.css b/packages/uikit-playground/src/App.css new file mode 100644 index 000000000000..10e4996c0f9a --- /dev/null +++ b/packages/uikit-playground/src/App.css @@ -0,0 +1,39 @@ +.App { + text-align: center; +} + +.App-logo { + height: 40vmin; + pointer-events: none; +} + +@media (prefers-reduced-motion: no-preference) { + .App-logo { + animation: App-logo-spin infinite 20s linear; + } +} + +.App-header { + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; +} + +.App-link { + color: #61dafb; +} + +@keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(360deg); + } +} diff --git a/packages/uikit-playground/src/App.tsx b/packages/uikit-playground/src/App.tsx new file mode 100644 index 000000000000..750c4df4795f --- /dev/null +++ b/packages/uikit-playground/src/App.tsx @@ -0,0 +1,18 @@ +import './App.css'; +import './cssVariables.css'; +import { BrowserRouter, Routes, Route } from 'react-router-dom'; + +import Playground from './Pages/Playground'; + +function App() { + return ( + + + } /> + } /> + + + ); +} + +export default App; diff --git a/packages/uikit-playground/src/Components/CodeEditor/Extensions/HighlightStyle.ts b/packages/uikit-playground/src/Components/CodeEditor/Extensions/HighlightStyle.ts new file mode 100644 index 000000000000..3329c3c6a859 --- /dev/null +++ b/packages/uikit-playground/src/Components/CodeEditor/Extensions/HighlightStyle.ts @@ -0,0 +1,14 @@ +import { HighlightStyle, syntaxHighlighting } from '@codemirror/language'; +import { tags as t } from '@lezer/highlight'; + +const highLightStyle = () => { + const style = HighlightStyle.define([ + { tag: t.literal, color: 'var(--RCPG-primary-color)' }, + { tag: t.bool, color: 'var(--RCPG-tertary-color)' }, + { tag: t.number, color: 'var(--RCPG-secondary-color)' }, + ]); + + return syntaxHighlighting(style); +}; + +export default highLightStyle(); diff --git a/packages/uikit-playground/src/Components/CodeEditor/Extensions/basicSetup.ts b/packages/uikit-playground/src/Components/CodeEditor/Extensions/basicSetup.ts new file mode 100644 index 000000000000..e5973a792217 --- /dev/null +++ b/packages/uikit-playground/src/Components/CodeEditor/Extensions/basicSetup.ts @@ -0,0 +1,59 @@ +import { + completionKeymap, + closeBrackets, + closeBracketsKeymap, +} from '@codemirror/autocomplete'; +import { + defaultKeymap, + history, + historyKeymap, + indentWithTab, +} from '@codemirror/commands'; +import { + defaultHighlightStyle, + syntaxHighlighting, + indentOnInput, + bracketMatching, + foldGutter, + foldKeymap, +} from '@codemirror/language'; +import { lintKeymap } from '@codemirror/lint'; +import { searchKeymap, highlightSelectionMatches } from '@codemirror/search'; +import type { Extension } from '@codemirror/state'; +import { + keymap, + drawSelection, + dropCursor, + rectangularSelection, + crosshairCursor, + lineNumbers, + EditorView, +} from '@codemirror/view'; + +const basicSetup: Extension = (() => [ + lineNumbers(), + history(), + foldGutter(), + drawSelection(), + dropCursor(), + indentOnInput(), + EditorView.lineWrapping, + syntaxHighlighting(defaultHighlightStyle, { fallback: true }), + bracketMatching(), + closeBrackets(), + rectangularSelection(), + crosshairCursor(), + highlightSelectionMatches(), + keymap.of([ + ...closeBracketsKeymap, + ...defaultKeymap, + ...searchKeymap, + ...historyKeymap, + ...foldKeymap, + ...completionKeymap, + ...lintKeymap, + indentWithTab, + ]), +])(); + +export default basicSetup; diff --git a/packages/uikit-playground/src/Components/CodeEditor/Extensions/index.ts b/packages/uikit-playground/src/Components/CodeEditor/Extensions/index.ts new file mode 100644 index 000000000000..9dda5b45b58d --- /dev/null +++ b/packages/uikit-playground/src/Components/CodeEditor/Extensions/index.ts @@ -0,0 +1,10 @@ +import { javascript } from '@codemirror/lang-javascript'; + +import highlightStyle from './HighlightStyle'; +import basicSetup from './basicSetup'; +import lint from './lint'; +import theme from './theme'; + +const extensions = [highlightStyle, javascript(), lint, basicSetup, ...theme]; + +export default extensions; diff --git a/packages/uikit-playground/src/Components/CodeEditor/Extensions/lint.ts b/packages/uikit-playground/src/Components/CodeEditor/Extensions/lint.ts new file mode 100644 index 000000000000..d8eb7870f0ec --- /dev/null +++ b/packages/uikit-playground/src/Components/CodeEditor/Extensions/lint.ts @@ -0,0 +1,5 @@ +import { esLint } from '@codemirror/lang-javascript'; +import { lintGutter, linter } from '@codemirror/lint'; +import Linter from 'eslint4b-prebuilt'; + +export default [lintGutter(), linter(esLint(new Linter()))]; diff --git a/packages/uikit-playground/src/Components/CodeEditor/Extensions/theme.ts b/packages/uikit-playground/src/Components/CodeEditor/Extensions/theme.ts new file mode 100644 index 000000000000..71938add617f --- /dev/null +++ b/packages/uikit-playground/src/Components/CodeEditor/Extensions/theme.ts @@ -0,0 +1,41 @@ +import type { Extension } from '@codemirror/state'; +import { EditorView } from '@codemirror/view'; + +const gutters: Extension = EditorView.theme({ + '.cm-gutters': { + backgroundColor: 'transparent', + border: 'none', + userSelect: 'none', + minWidth: '32px', + display: 'flex', + justifyContent: 'flex-end', + }, + + '.cm-activeLineGutter': { + backgroundColor: 'transparent', + }, +}); + +const selection: Extension = EditorView.theme({ + '.cm-selectionBackground': { + backgroundColor: 'var(--RCPG-secondary-color) !important', + opacity: 0.3, + }, + + '.cm-selectionMatch': { + backgroundColor: '#74808930 !important', + }, + + '.cm-matchingBracket': { + backgroundColor: 'transparent !important', + border: '1px solid #1d74f580', + }, +}); + +const line: Extension = EditorView.theme({ + '.cm-activeLine': { + backgroundColor: 'transparent !important', + }, +}); + +export default [gutters, selection, line] as const; diff --git a/packages/uikit-playground/src/Components/CodeEditor/index.tsx b/packages/uikit-playground/src/Components/CodeEditor/index.tsx new file mode 100644 index 000000000000..781c00c4821a --- /dev/null +++ b/packages/uikit-playground/src/Components/CodeEditor/index.tsx @@ -0,0 +1,75 @@ +import type { Extension } from '@codemirror/state'; +import { Box } from '@rocket.chat/fuselage'; +import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; +import json5 from 'json5'; +import { useEffect, useContext } from 'react'; + +import { context } from '../../Context'; +import { docAction } from '../../Context/action'; +import useCodeMirror from '../../hooks/useCodeMirror'; +import codePrettier from '../../utils/codePrettier'; + +type CodeMirrorProps = { + extensions?: Extension[]; +}; + +const CodeEditor = ({ extensions }: CodeMirrorProps) => { + const { state, dispatch } = useContext(context); + const { editor, changes, setValue } = useCodeMirror( + extensions, + json5.stringify(state.doc.payload, undefined, 4) + ); + const debounceValue = useDebouncedValue(changes?.value, 500); + + useEffect(() => { + console.log('a'); + if (!changes?.isDispatch) { + try { + const parsedCode = json5.parse(changes.value); + dispatch( + docAction({ + payload: parsedCode, + changedByEditor: false, + }) + ); + + dispatch(docAction({ payload: parsedCode })); + } catch (e) { + console.log(e); + // do nothing + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [changes?.value]); + + useEffect(() => { + console.log('b'); + if (!changes?.isDispatch) { + try { + const prettierCode = codePrettier(changes.value, changes.cursor); + setValue(prettierCode.formatted, { + cursor: prettierCode.cursorOffset, + }); + } catch (e) { + // do nothing + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [debounceValue]); + + useEffect(() => { + console.log('c'); + if (!state.doc.changedByEditor) { + setValue(JSON.stringify(state.doc.payload, undefined, 4), {}); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [state.doc.payload]); + + return ( + <> + + + ); +}; + +export default CodeEditor; diff --git a/packages/uikit-playground/src/Components/ComponentSideBar/ScrollableSideBar.tsx b/packages/uikit-playground/src/Components/ComponentSideBar/ScrollableSideBar.tsx new file mode 100644 index 000000000000..1c75c93cbf6a --- /dev/null +++ b/packages/uikit-playground/src/Components/ComponentSideBar/ScrollableSideBar.tsx @@ -0,0 +1,24 @@ +import { css } from '@rocket.chat/css-in-js'; +import { Scrollable, Box } from '@rocket.chat/fuselage'; +import type { FC } from 'react'; + +import BlocksTree from '../../Payload/BlocksTree'; +import DropDown from '../DropDown'; + +const ScrollableSideBar: FC = () => ( + + + + + +); + +export default ScrollableSideBar; diff --git a/packages/uikit-playground/src/Components/ComponentSideBar/SideBar.tsx b/packages/uikit-playground/src/Components/ComponentSideBar/SideBar.tsx new file mode 100644 index 000000000000..0cf71a6a159b --- /dev/null +++ b/packages/uikit-playground/src/Components/ComponentSideBar/SideBar.tsx @@ -0,0 +1,46 @@ +import { css } from '@rocket.chat/css-in-js'; +import { Box } from '@rocket.chat/fuselage'; +import type { FC } from 'react'; +import { useEffect, useContext } from 'react'; + +import { context } from '../../Context'; +import { sidebarToggleAction } from '../../Context/action'; +import ScrollableSideBar from './ScrollableSideBar'; +import SliderBtn from './SliderBtn'; + +const SideBar: FC = () => { + const { state, dispatch } = useContext(context); + + useEffect(() => { + dispatch(sidebarToggleAction(false)); + }, [state?.isMobile, dispatch]); + + const slide = state?.isMobile + ? css` + width: 100%; + user-select: none; + transform: translateX(${state?.sideBarToggle ? '0' : '-100%'}); + transition: var(--animation-default); + ` + : css` + width: var(--sidebar-width); + user-select: none; + transition: var(--animation-default); + `; + + return ( + + + + + ); +}; + +export default SideBar; diff --git a/packages/uikit-playground/src/Components/ComponentSideBar/SliderBtn.tsx b/packages/uikit-playground/src/Components/ComponentSideBar/SliderBtn.tsx new file mode 100644 index 000000000000..a328ee395074 --- /dev/null +++ b/packages/uikit-playground/src/Components/ComponentSideBar/SliderBtn.tsx @@ -0,0 +1,116 @@ +import { css } from '@rocket.chat/css-in-js'; +import { Box, Label } from '@rocket.chat/fuselage'; +import type { FC } from 'react'; +import { useContext } from 'react'; + +import { context } from '../../Context'; +import { sidebarToggleAction } from '../../Context/action'; + +const SliderBtn: FC = () => { + const { + state: { sideBarToggle, isMobile }, + dispatch, + } = useContext(context); + const slideBtnAnimation = sideBarToggle + ? css` + clip-path: polygon( + 10% 0, + 50% 40%, + 90% 0, + 100% 10%, + 60% 50%, + 100% 90%, + 90% 100%, + 50% 60%, + 10% 100%, + 0 90%, + 40% 50%, + 0 10% + ); + cursor: pointer; + transition: var(--animation-default); + ` + : css` + clip-path: polygon( + 32% 35%, + 32% 35%, + 79% 0, + 87% 10%, + 32% 50%, + 87% 90%, + 79% 100%, + 32% 64%, + 32% 65%, + 13% 50%, + 13% 50%, + 13% 50% + ); + transform: rotate(180deg); + transition: var(--animation-default); + `; + + const toggleStyle = !isMobile + ? css` + left: 0px; + ` + : sideBarToggle + ? css` + right: 0; + transition: var(--animation-default); + ` + : css` + right: 0; + transform: translateX(100%); + cursor: pointer; + transition: var(--animation-default); + `; + + return ( + + !sideBarToggle && dispatch(sidebarToggleAction(!sideBarToggle)) + } + zIndex={1} + className={toggleStyle} + > + + {isMobile && ( + + sideBarToggle && dispatch(sidebarToggleAction(!sideBarToggle)) + } + className={css` + cursor: pointer; + `} + > + + + )} + + ); +}; + +export default SliderBtn; diff --git a/packages/uikit-playground/src/Components/ComponentSideBar/index.tsx b/packages/uikit-playground/src/Components/ComponentSideBar/index.tsx new file mode 100644 index 000000000000..c90236635b47 --- /dev/null +++ b/packages/uikit-playground/src/Components/ComponentSideBar/index.tsx @@ -0,0 +1 @@ +export { default } from './SideBar'; diff --git a/packages/uikit-playground/src/Components/Draggable/DraggableList.tsx b/packages/uikit-playground/src/Components/Draggable/DraggableList.tsx new file mode 100644 index 000000000000..76e7af15538d --- /dev/null +++ b/packages/uikit-playground/src/Components/Draggable/DraggableList.tsx @@ -0,0 +1,51 @@ +import type { LayoutBlock } from '@rocket.chat/ui-kit'; +import * as React from 'react'; +import type { OnDragEndResponder } from 'react-beautiful-dnd'; +import { DragDropContext, Droppable } from 'react-beautiful-dnd'; + +import DraggableListItem from './DraggableListItem'; + +export type Block = { + id: string; + payload: LayoutBlock; +}; + +export type DraggableListProps = { + blocks: Block[]; + surface?: number; + onDragEnd: OnDragEndResponder; +}; + +const DraggableList = React.memo( + ({ blocks, surface, onDragEnd }: DraggableListProps) => ( + <> + + <> + + {(provided) => ( +
+ <> + {blocks.map((block, index) => ( + + ))} + {provided.placeholder} + +
+ )} +
+ +
+ + ) +); + +export default DraggableList; diff --git a/packages/uikit-playground/src/Components/Draggable/DraggableListItem.tsx b/packages/uikit-playground/src/Components/Draggable/DraggableListItem.tsx new file mode 100644 index 000000000000..d06d2769f15e --- /dev/null +++ b/packages/uikit-playground/src/Components/Draggable/DraggableListItem.tsx @@ -0,0 +1,34 @@ +import { Draggable } from 'react-beautiful-dnd'; + +import RenderPayload from '../Preview/Display/RenderPayload/RenderPayload'; +import type { Block } from './DraggableList'; + +export type DraggableListItemProps = { + block: Block; + surface: number; + index: number; +}; + +const DraggableListItem = ({ + block, + surface, + index, +}: DraggableListItemProps) => ( + + {(provided) => ( +
+ +
+ )} +
+); + +export default DraggableListItem; diff --git a/packages/uikit-playground/src/Components/DropDown/DropDown.tsx b/packages/uikit-playground/src/Components/DropDown/DropDown.tsx new file mode 100644 index 000000000000..dd6470a4d632 --- /dev/null +++ b/packages/uikit-playground/src/Components/DropDown/DropDown.tsx @@ -0,0 +1,34 @@ +import { Box } from '@rocket.chat/fuselage'; +import { Fragment } from 'react'; + +import Items from './Items'; +import type { Item, ItemBranch } from './types'; + +interface DropDownProps { + readonly BlocksTree: Item; +} + +const DropDown = ({ BlocksTree }: DropDownProps) => { + const layer = 1; + + const recursiveComponentTree = (branch: ItemBranch, layer: number) => ( + + {branch.branches && + branch.branches.map((branch: ItemBranch, index: number) => ( + + {recursiveComponentTree(branch, layer + 1)} + + ))} + + ); + + return ( + + {BlocksTree.map((branch: ItemBranch, i: number) => ( + {recursiveComponentTree(branch, layer)} + ))} + + ); +}; + +export default DropDown; diff --git a/packages/uikit-playground/src/Components/DropDown/Items.tsx b/packages/uikit-playground/src/Components/DropDown/Items.tsx new file mode 100644 index 000000000000..f37822c564bc --- /dev/null +++ b/packages/uikit-playground/src/Components/DropDown/Items.tsx @@ -0,0 +1,66 @@ +import { css } from '@rocket.chat/css-in-js'; +import { Box, Label, Chevron } from '@rocket.chat/fuselage'; +import { useState, useContext } from 'react'; + +import { context } from '../../Context'; +import ItemsIcon from './ItemsIcon'; +import { itemStyle, labelStyle } from './itemsStyle'; +import type { ItemProps } from './types'; +import { docAction } from '../../Context/action'; + +const Items = ({ label, children, layer, payload }: ItemProps) => { + const [isOpen, toggleItemOpen] = useState(layer === 1); + const [hover, setHover] = useState(false); + const { state, dispatch } = useContext(context); + + const itemClickHandler = () => { + toggleItemOpen(!isOpen); + payload && + dispatch( + docAction({ + payload: [...state.doc.payload, payload[0]], + changedByEditor: false, + }) + ); + }; + + return ( + + setHover(true)} + onMouseLeave={() => setHover(false)} + onClick={itemClickHandler} + > + + {children && children.length > 0 && ( + + + + )} + + + + + + + {isOpen && children} + + ); +}; + +export default Items; diff --git a/packages/uikit-playground/src/Components/DropDown/ItemsIcon.tsx b/packages/uikit-playground/src/Components/DropDown/ItemsIcon.tsx new file mode 100644 index 000000000000..9a1d74f3f1f1 --- /dev/null +++ b/packages/uikit-playground/src/Components/DropDown/ItemsIcon.tsx @@ -0,0 +1,28 @@ +import { Icon } from '@rocket.chat/fuselage'; + +const ItemsIcon = ({ + layer, + lastNode, + hover, +}: { + layer: number; + lastNode: boolean; + hover: boolean; +}) => { + const selectIcon = (layer: number, hover: boolean) => { + if (layer === 1) { + return ( + + ); + } + if (lastNode) { + return ; + } + return ( + + ); + }; + return <>{selectIcon(layer, hover)}; +}; + +export default ItemsIcon; diff --git a/packages/uikit-playground/src/Components/DropDown/index.tsx b/packages/uikit-playground/src/Components/DropDown/index.tsx new file mode 100644 index 000000000000..d76df1b0ff42 --- /dev/null +++ b/packages/uikit-playground/src/Components/DropDown/index.tsx @@ -0,0 +1 @@ +export { default } from './DropDown'; diff --git a/packages/uikit-playground/src/Components/DropDown/itemsStyle.ts b/packages/uikit-playground/src/Components/DropDown/itemsStyle.ts new file mode 100644 index 000000000000..da9c9ff0b2c5 --- /dev/null +++ b/packages/uikit-playground/src/Components/DropDown/itemsStyle.ts @@ -0,0 +1,45 @@ +import { css } from '@rocket.chat/css-in-js'; + +export const itemStyle = (layer: number, hover: boolean) => { + const style = css` + cursor: pointer; + padding-left: ${10 + (layer - 1) * 16}px; + background-color: ${hover ? 'var(--RCPG-primary-color)' : 'transparent'}; + `; + return style; +}; + +export const labelStyle = (layer: number, hover: boolean) => { + let customStyle; + const basicStyle = css` + cursor: pointer !important; + padding-left: 4px !important; + `; + switch (layer) { + case 1: + customStyle = css` + font-weight: 700; + font-size: 14px; + letter-spacing: 0.3px; + color: ${hover ? '#fff' : '#999'}; + text-transform: uppercase; + `; + break; + case 2: + customStyle = css` + letter-spacing: 0.1px; + font-size: 12px; + color: ${hover ? '#fff' : '#555'}; + text-transform: capitalize; + `; + break; + default: + customStyle = css` + font-size: 12px; + color: ${hover ? '#fff' : '#555'}; + text-transform: capitalize; + `; + break; + } + return [customStyle, basicStyle]; +}; diff --git a/packages/uikit-playground/src/Components/DropDown/types.ts b/packages/uikit-playground/src/Components/DropDown/types.ts new file mode 100644 index 000000000000..3b0c505d38f9 --- /dev/null +++ b/packages/uikit-playground/src/Components/DropDown/types.ts @@ -0,0 +1,16 @@ +import type { LayoutBlock } from '@rocket.chat/ui-kit'; + +export type ItemProps = { + label: string; + layer: number; + payload?: readonly LayoutBlock[]; + children?: ReadonlyArray; +}; + +export type ItemBranch = { + label: string; + branches?: Item; + payload?: readonly LayoutBlock[]; +}; + +export type Item = ItemBranch[]; diff --git a/packages/uikit-playground/src/Components/NavBar/BurgerIcon/BurgerIcon.tsx b/packages/uikit-playground/src/Components/NavBar/BurgerIcon/BurgerIcon.tsx new file mode 100644 index 000000000000..af02130ca4e0 --- /dev/null +++ b/packages/uikit-playground/src/Components/NavBar/BurgerIcon/BurgerIcon.tsx @@ -0,0 +1,25 @@ +import { usePrefersReducedMotion } from '@rocket.chat/fuselage-hooks'; +import type { ReactElement, ReactNode } from 'react'; +import { useContext } from 'react'; + +import { context } from '../../../Context'; +import Line from './Line'; +import Wrapper from './Wrapper'; + +const BurgerIcon = ({ children }: { children?: ReactNode }): ReactElement => { + const isReducedMotionPreferred = usePrefersReducedMotion(); + const { + state: { navMenuToggle }, + } = useContext(context); + + return ( + + + + + {children} + + ); +}; + +export default BurgerIcon; diff --git a/packages/uikit-playground/src/Components/NavBar/BurgerIcon/Line.tsx b/packages/uikit-playground/src/Components/NavBar/BurgerIcon/Line.tsx new file mode 100644 index 000000000000..e1ddfed3ac0b --- /dev/null +++ b/packages/uikit-playground/src/Components/NavBar/BurgerIcon/Line.tsx @@ -0,0 +1,52 @@ +import { css } from '@rocket.chat/css-in-js'; +import { Box } from '@rocket.chat/fuselage'; +import type { ReactElement } from 'react'; + +const Line = ({ + animated, + moved, +}: { + animated: boolean; + moved?: boolean; +}): ReactElement => { + const animatedStyle = animated + ? css` + will-change: transform; + transition: transform 0.1s ease-out; + ` + : ''; + + const movedStyle = moved + ? css` + &:nth-child(1), + &:nth-child(3) { + transform-origin: 50%, 50%, 0; + } + &:nth-child(1) { + transform: translate(-25%, 3px) rotate(-45deg) scale(0.5, 1); + } + [dir='rtl'] &:nth-child(1) { + transform: translate(25%, 3px) rotate(45deg) scale(0.5, 1); + } + &:nth-child(3) { + transform: translate(-25%, -3px) rotate(45deg) scale(0.5, 1); + } + [dir='rtl'] &:nth-child(3) { + transform: translate(25%, -3px) rotate(-45deg) scale(0.5, 1); + } + ` + : ''; + + return ( +