diff --git a/.changeset/angry-rocks-try.md b/.changeset/angry-rocks-try.md deleted file mode 100644 index 8072b9db48fb..000000000000 --- a/.changeset/angry-rocks-try.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@rocket.chat/meteor": patch ---- - -Fixed an issue causing monitors to dissapear from a saved unit every time a user saved the item. This was caused by the UI not sending the correct _id of the monitors that were already saved, and this caused the Backend to ignore them and remove from the list. diff --git a/.changeset/breezy-geckos-sparkle.md b/.changeset/breezy-geckos-sparkle.md deleted file mode 100644 index c64ffe920282..000000000000 --- a/.changeset/breezy-geckos-sparkle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rocket.chat/meteor': patch ---- - -Fix an issue where read receipts menu item wasn't considering the enabled setting to be displayed diff --git a/.changeset/chilly-poems-explode.md b/.changeset/chilly-poems-explode.md deleted file mode 100644 index 17acf3c5ba85..000000000000 --- a/.changeset/chilly-poems-explode.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@rocket.chat/meteor": minor -"@rocket.chat/core-typings": minor -"@rocket.chat/i18n": patch ---- - -Introduced a tab layout to the users page and implemented a tab called "All" that lists all users. diff --git a/.changeset/cold-beds-hope.md b/.changeset/cold-beds-hope.md deleted file mode 100644 index 33fc910e424f..000000000000 --- a/.changeset/cold-beds-hope.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rocket.chat/meteor': patch ---- - -Fixes an issue not allowing override retention policy in channels diff --git a/.changeset/cuddly-owls-join.md b/.changeset/cuddly-owls-join.md deleted file mode 100644 index 0ace3d145d37..000000000000 --- a/.changeset/cuddly-owls-join.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rocket.chat/meteor': patch ---- - -Fixed an issue that prevented CAS users from being merged with existing user data on login diff --git a/.changeset/eighty-wasps-kneel.md b/.changeset/eighty-wasps-kneel.md new file mode 100644 index 000000000000..d8f297de64c3 --- /dev/null +++ b/.changeset/eighty-wasps-kneel.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +Fixed an issue with how the UI checked for permissions when deciding if editing or deleting a message by moderators users diff --git a/.changeset/fair-grapes-thank.md b/.changeset/fair-grapes-thank.md deleted file mode 100644 index 2d8962f40db9..000000000000 --- a/.changeset/fair-grapes-thank.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@rocket.chat/meteor": minor ---- - -Allow visitors & integrations to access downloaded files after a room has closed. This was a known limitation in our codebase, where visitors were only able to access uploaded files in a livechat conversation while the conversation was open. diff --git a/.changeset/five-shoes-fly.md b/.changeset/five-shoes-fly.md new file mode 100644 index 000000000000..da462e1508c7 --- /dev/null +++ b/.changeset/five-shoes-fly.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': patch +--- + +Fixed codeBlock styles in light mode diff --git a/.changeset/flat-starfishes-crash.md b/.changeset/flat-starfishes-crash.md deleted file mode 100644 index 9c5bb2425f19..000000000000 --- a/.changeset/flat-starfishes-crash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rocket.chat/meteor': patch ---- - -Fixed a problem in how server was processing errors that was sending 2 ephemeral error messages when @all or @here were used while they were disabled via permissions diff --git a/.changeset/fresh-students-remember.md b/.changeset/fresh-students-remember.md deleted file mode 100644 index 50b422f6b7dd..000000000000 --- a/.changeset/fresh-students-remember.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@rocket.chat/meteor": patch ---- - -Fixed an issue where translations would fallback to english some of the times. diff --git a/.changeset/gorgeous-lizards-shave.md b/.changeset/gorgeous-lizards-shave.md deleted file mode 100644 index d02d3cb80599..000000000000 --- a/.changeset/gorgeous-lizards-shave.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@rocket.chat/meteor": minor -"@rocket.chat/livechat": minor ---- - -Makes the triggers fired by the condition `after-guest-registration` persist on the livechat client, it will persist through reloads and pagination, only reseting when a conversation is closed (no changes were done on the agent side of the conversation) diff --git a/.changeset/lazy-gorilas-shop.md b/.changeset/lazy-gorilas-shop.md deleted file mode 100644 index c71610f703fc..000000000000 --- a/.changeset/lazy-gorilas-shop.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@rocket.chat/meteor": patch -"@rocket.chat/i18n": patch ---- - -Fixed an issue with object storage settings that was not allowing admins to decide if files generated via "Export conversation" feature were being proxied through server or not. diff --git a/.changeset/nasty-swans-compete.md b/.changeset/nasty-swans-compete.md deleted file mode 100644 index 7cf912e3f075..000000000000 --- a/.changeset/nasty-swans-compete.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@rocket.chat/meteor": patch -"@rocket.chat/core-services": patch -"@rocket.chat/omnichannel-services": patch -"@rocket.chat/pdf-worker": patch ---- - -Fixed multiple issues with PDF generation logic when a quoted message was too big to fit in one single page. This was causing an internal infinite loop within the library (as it tried to make it fit, failing and then trying to fit on next page where the same happened thus causing a loop). -The library was not able to break down some nested views and thus was trying to fit the whole quote on one single page. Logic was updated to allow wrapping of the contents when messages are quoted (so they can span multiple lines) and removed a bunch of unnecesary views from the code. diff --git a/.changeset/ninety-rivers-mix.md b/.changeset/ninety-rivers-mix.md deleted file mode 100644 index fbd10b2a04d1..000000000000 --- a/.changeset/ninety-rivers-mix.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@rocket.chat/meteor": patch -"@rocket.chat/rest-typings": minor ---- - -Fixed issue with "Export room as file" feature (`rooms.export` endpoint) generating an empty export when given an invalid date diff --git a/.changeset/rare-colts-repair.md b/.changeset/rare-colts-repair.md new file mode 100644 index 000000000000..9011de6ff483 --- /dev/null +++ b/.changeset/rare-colts-repair.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': patch +--- + +Fixes an issue not rendering the proper error and empty state on users in role table diff --git a/.changeset/rich-bananas-complain.md b/.changeset/rich-bananas-complain.md deleted file mode 100644 index 9ddaf098c948..000000000000 --- a/.changeset/rich-bananas-complain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rocket.chat/meteor': patch ---- - -Fixed an issue on Users converter that was not returning the `statusText` property from users even when the typing indicated property existed. diff --git a/.changeset/serious-bottles-tie.md b/.changeset/serious-bottles-tie.md new file mode 100644 index 000000000000..e12bb94a5310 --- /dev/null +++ b/.changeset/serious-bottles-tie.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': patch +--- + +Fix user not being set as online when setting "Use REST instead of websocket for Meteor calls" is disabled diff --git a/.changeset/shiny-crabs-peel.md b/.changeset/shiny-crabs-peel.md deleted file mode 100644 index f4d066827bfc..000000000000 --- a/.changeset/shiny-crabs-peel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rocket.chat/fuselage-ui-kit': patch ---- - -Fix translation param on video conf joined message diff --git a/.changeset/short-coins-enjoy.md b/.changeset/short-coins-enjoy.md new file mode 100644 index 000000000000..d47017030fcb --- /dev/null +++ b/.changeset/short-coins-enjoy.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': patch +--- + +Fixed an issue where apps installed via the Marketplace would not be shown in the installed list if the app is unpublished diff --git a/.changeset/shy-oranges-provide.md b/.changeset/shy-oranges-provide.md deleted file mode 100644 index 7141a58da575..000000000000 --- a/.changeset/shy-oranges-provide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@rocket.chat/meteor": patch ---- - -Fixes link image preview not opening in gallery mode diff --git a/.changeset/silly-clocks-return.md b/.changeset/silly-clocks-return.md deleted file mode 100644 index 0505580a477a..000000000000 --- a/.changeset/silly-clocks-return.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@rocket.chat/omnichannel-services': patch -'@rocket.chat/core-services': patch -'@rocket.chat/meteor': patch ---- - -Fixed error handling for files bigger than NATS max allowed payload. This should prevent PDFs from erroring out when generating from rooms that contain heavy images. diff --git a/.changeset/strange-bears-dance.md b/.changeset/strange-bears-dance.md deleted file mode 100644 index 49ea972c8fe4..000000000000 --- a/.changeset/strange-bears-dance.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rocket.chat/meteor': minor ---- - -Adds CheckOption to departments multi selects improving options visibility state diff --git a/.changeset/strong-humans-bow.md b/.changeset/strong-humans-bow.md deleted file mode 100644 index b718cbe7fedd..000000000000 --- a/.changeset/strong-humans-bow.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@rocket.chat/fuselage-ui-kit": minor -"@rocket.chat/ui-kit": minor ---- - -Introduced new elements for apps to select channels diff --git a/.changeset/sweet-kiwis-scream.md b/.changeset/sweet-kiwis-scream.md new file mode 100644 index 000000000000..95a094f2ac40 --- /dev/null +++ b/.changeset/sweet-kiwis-scream.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": minor +--- + +Clicking on a message attachment link in the Desktop App will now initiate a direct download of the attachment only when the attachment is not a PDF file diff --git a/.changeset/tall-wombats-love.md b/.changeset/tall-wombats-love.md deleted file mode 100644 index 80f4d2c494da..000000000000 --- a/.changeset/tall-wombats-love.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rocket.chat/meteor': patch ---- - -Replaces the burger menu with an appropriate button fixing the semantics and mismatching color diff --git a/.changeset/tidy-apes-fry.md b/.changeset/tidy-apes-fry.md new file mode 100644 index 000000000000..ee3922fa350c --- /dev/null +++ b/.changeset/tidy-apes-fry.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +Fixed inverted navigation direction in the image gallery diff --git a/.changeset/unlucky-berries-guess.md b/.changeset/unlucky-berries-guess.md deleted file mode 100644 index 5a4cc9aba3e9..000000000000 --- a/.changeset/unlucky-berries-guess.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rocket.chat/meteor': minor ---- - -Replace the read receipt receipt indicator in order to improve the accessibility complience diff --git a/.changeset/warm-squids-deliver.md b/.changeset/warm-squids-deliver.md deleted file mode 100644 index 0ec0a9407993..000000000000 --- a/.changeset/warm-squids-deliver.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rocket.chat/meteor': minor ---- - -Changes the scrollbar color in order to improve the contrast and accessibility compliance diff --git a/.changeset/weak-starfishes-fail.md b/.changeset/weak-starfishes-fail.md deleted file mode 100644 index 38e510229f6e..000000000000 --- a/.changeset/weak-starfishes-fail.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rocket.chat/meteor': patch ---- - -Fixes the missing spacing on don`t ask again checkbox inside modals diff --git a/.changeset/weak-turkeys-sit.md b/.changeset/weak-turkeys-sit.md deleted file mode 100644 index c4673b9d049d..000000000000 --- a/.changeset/weak-turkeys-sit.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@rocket.chat/meteor": patch ---- - -Fixed a bad behavior with the interaction between OTR system messages & trash collection. We use trash collection as a temporary storage that holds recently deleted items from some collections. Messages is one of those. This was causing "User joined OTR" messages to be viewable when querying the trash collection. -Since OTR messages are by definition private, code was updated to bypass trash collection when removing these special messages. - -Note: this only applies to these system messages. OTR user's messages are not stored on the database. diff --git a/.changeset/wicked-points-deliver.md b/.changeset/wicked-points-deliver.md deleted file mode 100644 index 91985578917f..000000000000 --- a/.changeset/wicked-points-deliver.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@rocket.chat/meteor': patch ---- - -This fuselage`s bump fixes: -- The message toolbar visibility on hover (Firefox ESR) -- `Bubble` missing font-family - -[more details](https://github.com/RocketChat/fuselage/releases/tag/%40rocket.chat%2Ffuselage%400.53.7) diff --git a/.changeset/wild-carrots-know.md b/.changeset/wild-carrots-know.md new file mode 100644 index 000000000000..6403b5fd0bfd --- /dev/null +++ b/.changeset/wild-carrots-know.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +Remove password change reason when the `request password change` option is set to false diff --git a/.changeset/wild-teachers-design.md b/.changeset/wild-teachers-design.md deleted file mode 100644 index f49f4549e762..000000000000 --- a/.changeset/wild-teachers-design.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@rocket.chat/meteor": minor -"@rocket.chat/core-typings": minor -"@rocket.chat/i18n": minor ---- - -Added "Rocket.Chat Cloud Workspace ID" to workspace statistics page diff --git a/.changeset/wise-pianos-explode.md b/.changeset/wise-pianos-explode.md deleted file mode 100644 index 3473275e20ab..000000000000 --- a/.changeset/wise-pianos-explode.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@rocket.chat/meteor": patch ---- - -Fixed issue with external users being able to reset their passwords even when the "Allow Password Change for OAuth Users" setting is disabled diff --git a/.changeset/yellow-lies-judge.md b/.changeset/yellow-lies-judge.md deleted file mode 100644 index 15bc8e0819bd..000000000000 --- a/.changeset/yellow-lies-judge.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@rocket.chat/meteor": patch ---- - -fixed Engagement Dashboard and Device Management admin pages loading indefinitely diff --git a/.changeset/young-yaks-suffer.md b/.changeset/young-yaks-suffer.md deleted file mode 100644 index b3a1d7b09fef..000000000000 --- a/.changeset/young-yaks-suffer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rocket.chat/meteor': patch ---- - -bump fuselage adding `AttachmentAuthorName` missing color token diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8393b0d9ec8f..b16ab459d6bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -629,7 +629,7 @@ jobs: strategy: matrix: - service: ['account', 'authorization', 'ddp-streamer', 'presence', 'stream-hub'] + service: ['account', 'authorization', 'ddp-streamer', 'omnichannel-transcript', 'presence', 'queue-worker', 'stream-hub'] steps: - name: Login to DockerHub diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index b074212964eb..0ee119fe43aa 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -11,8 +11,8 @@ jobs: steps: - uses: actions/stale@v5 with: - days-before-issue-stale: 10 - days-before-issue-close: 4 + days-before-issue-stale: 14 + days-before-issue-close: 14 any-of-labels: 'stat: need more info,stat: waiting response' stale-issue-label: "stat: no response" stale-issue-message: "This issue has been marked as stale because there has been no further activity in the last 10 days. If the issue remains stale for the next 4 days (a total of 14 days with no activity), then it will be assumed that the question has been resolved and the issue will be automatically closed." diff --git a/apps/meteor/CHANGELOG.md b/apps/meteor/CHANGELOG.md index 5039151d35bc..1f1b39852c7b 100644 --- a/apps/meteor/CHANGELOG.md +++ b/apps/meteor/CHANGELOG.md @@ -1,5 +1,275 @@ # @rocket.chat/meteor +## 6.9.0 + +### Minor Changes + +- ([#31917](https://github.com/RocketChat/Rocket.Chat/pull/31917)) Introduced a tab layout to the users page and implemented a tab called "All" that lists all users. + +- ([#32439](https://github.com/RocketChat/Rocket.Chat/pull/32439)) Allow visitors & integrations to access downloaded files after a room has closed. This was a known limitation in our codebase, where visitors were only able to access uploaded files in a livechat conversation while the conversation was open. + +- ([#32233](https://github.com/RocketChat/Rocket.Chat/pull/32233)) Makes the triggers fired by the condition `after-guest-registration` persist on the livechat client, it will persist through reloads and pagination, only reseting when a conversation is closed (no changes were done on the agent side of the conversation) + +- ([#32193](https://github.com/RocketChat/Rocket.Chat/pull/32193)) Adds CheckOption to departments multi selects improving options visibility state + +- ([#32317](https://github.com/RocketChat/Rocket.Chat/pull/32317)) Replace the read receipt receipt indicator in order to improve the accessibility complience + +- ([#32341](https://github.com/RocketChat/Rocket.Chat/pull/32341)) Changes the scrollbar color in order to improve the contrast and accessibility compliance + +- ([#32298](https://github.com/RocketChat/Rocket.Chat/pull/32298)) Added "Rocket.Chat Cloud Workspace ID" to workspace statistics page + +### Patch Changes + +- ([#32393](https://github.com/RocketChat/Rocket.Chat/pull/32393)) Fixed an issue causing monitors to dissapear from a saved unit every time a user saved the item. This was caused by the UI not sending the correct \_id of the monitors that were already saved, and this caused the Backend to ignore them and remove from the list. + +- ([#31695](https://github.com/RocketChat/Rocket.Chat/pull/31695)) Fix an issue where read receipts menu item wasn't considering the enabled setting to be displayed + +- Bump @rocket.chat/meteor version. + +- Bump @rocket.chat/meteor version. + +- Bump @rocket.chat/meteor version. + +- ([#32454](https://github.com/RocketChat/Rocket.Chat/pull/32454)) Fixes an issue not allowing override retention policy in channels + +- ([#32444](https://github.com/RocketChat/Rocket.Chat/pull/32444)) Fixed an issue that prevented CAS users from being merged with existing user data on login + +- ([#32289](https://github.com/RocketChat/Rocket.Chat/pull/32289)) Fixed a problem in how server was processing errors that was sending 2 ephemeral error messages when @all or @here were used while they were disabled via permissions + +- ([#32348](https://github.com/RocketChat/Rocket.Chat/pull/32348)) Fixed an issue where translations would fallback to english some of the times. + +- ([#32182](https://github.com/RocketChat/Rocket.Chat/pull/32182)) Fixed an issue with object storage settings that was not allowing admins to decide if files generated via "Export conversation" feature were being proxied through server or not. + +- ([#32311](https://github.com/RocketChat/Rocket.Chat/pull/32311)) Fixed multiple issues with PDF generation logic when a quoted message was too big to fit in one single page. This was causing an internal infinite loop within the library (as it tried to make it fit, failing and then trying to fit on next page where the same happened thus causing a loop). + The library was not able to break down some nested views and thus was trying to fit the whole quote on one single page. Logic was updated to allow wrapping of the contents when messages are quoted (so they can span multiple lines) and removed a bunch of unnecesary views from the code. +- ([#32364](https://github.com/RocketChat/Rocket.Chat/pull/32364)) Fixed issue with "Export room as file" feature (`rooms.export` endpoint) generating an empty export when given an invalid date + +- ([#32314](https://github.com/RocketChat/Rocket.Chat/pull/32314)) Fixed an issue on Users converter that was not returning the `statusText` property from users even when the typing indicated property existed. + +- ([#32500](https://github.com/RocketChat/Rocket.Chat/pull/32500)) Fix user not being set as online when setting "Use REST instead of websocket for Meteor calls" is disabled + +- ([#32391](https://github.com/RocketChat/Rocket.Chat/pull/32391)) Fixes link image preview not opening in gallery mode + +- ([#32318](https://github.com/RocketChat/Rocket.Chat/pull/32318)) Fixed error handling for files bigger than NATS max allowed payload. This should prevent PDFs from erroring out when generating from rooms that contain heavy images. + +- ([#32479](https://github.com/RocketChat/Rocket.Chat/pull/32479)) Executing a logout and login action in the same "tab/instance", some streams were not being recreated, causing countless types of bugs. + + PS: as a workaround reloading after logout or login in also solves the problem. + +- ([#32345](https://github.com/RocketChat/Rocket.Chat/pull/32345)) Replaces the burger menu with an appropriate button fixing the semantics and mismatching color + +- ([#32414](https://github.com/RocketChat/Rocket.Chat/pull/32414)) Fixes the missing spacing on don`t ask again checkbox inside modals + +- ([#32269](https://github.com/RocketChat/Rocket.Chat/pull/32269)) Fixed a bad behavior with the interaction between OTR system messages & trash collection. We use trash collection as a temporary storage that holds recently deleted items from some collections. Messages is one of those. This was causing "User joined OTR" messages to be viewable when querying the trash collection. + Since OTR messages are by definition private, code was updated to bypass trash collection when removing these special messages. + + Note: this only applies to these system messages. OTR user's messages are not stored on the database. + +- ([#32415](https://github.com/RocketChat/Rocket.Chat/pull/32415)) This fuselage`s bump fixes: + + - The message toolbar visibility on hover (Firefox ESR) + - `Bubble` missing font-family + + [more details](https://github.com/RocketChat/fuselage/releases/tag/%40rocket.chat%2Ffuselage%400.53.7) + +- ([#32398](https://github.com/RocketChat/Rocket.Chat/pull/32398)) Fixed issue with external users being able to reset their passwords even when the "Allow Password Change for OAuth Users" setting is disabled + +- ([#32284](https://github.com/RocketChat/Rocket.Chat/pull/32284)) fixed Engagement Dashboard and Device Management admin pages loading indefinitely + +- ([#32342](https://github.com/RocketChat/Rocket.Chat/pull/32342)) bump fuselage adding `AttachmentAuthorName` missing color token + +-
Updated dependencies [ff4e396416, bc50dd54a2, ad86761209, f83bd56cc5, 6205ef14f0, 724ba3a729, ee5cdfc367, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/i18n@0.4.0 + - @rocket.chat/core-services@0.3.15 + - @rocket.chat/omnichannel-services@0.1.15 + - @rocket.chat/pdf-worker@0.0.39 + - @rocket.chat/rest-typings@6.9.0 + - @rocket.chat/fuselage-ui-kit@7.0.0 + - @rocket.chat/ui-kit@0.34.0 + - @rocket.chat/api-client@0.1.33 + - @rocket.chat/license@0.1.15 + - @rocket.chat/presence@0.1.15 + - @rocket.chat/apps@0.0.6 + - @rocket.chat/cron@0.0.35 + - @rocket.chat/gazzodown@7.0.0 + - @rocket.chat/model-typings@0.4.1 + - @rocket.chat/ui-contexts@7.0.0 + - @rocket.chat/web-ui-registration@7.0.0 + - @rocket.chat/server-cloud-communication@0.0.2 + - @rocket.chat/models@0.0.39 + - @rocket.chat/ui-theming@0.1.2 + - @rocket.chat/ui-avatar@3.0.0 + - @rocket.chat/ui-client@7.0.0 + - @rocket.chat/ui-video-conf@7.0.0 + - @rocket.chat/instance-status@0.0.39 +
+ +## 6.9.0-rc.2 + +### Patch Changes + +- Bump @rocket.chat/meteor version. + +- ([#32500](https://github.com/RocketChat/Rocket.Chat/pull/32500)) Fix user not being set as online when setting "Use REST instead of websocket for Meteor calls" is disabled + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/rest-typings@6.9.0-rc.2 + - @rocket.chat/api-client@0.1.33-rc.2 + - @rocket.chat/license@0.1.15-rc.2 + - @rocket.chat/omnichannel-services@0.1.15-rc.2 + - @rocket.chat/pdf-worker@0.0.39-rc.2 + - @rocket.chat/presence@0.1.15-rc.2 + - @rocket.chat/apps@0.0.6-rc.2 + - @rocket.chat/core-services@0.3.15-rc.2 + - @rocket.chat/cron@0.0.35-rc.2 + - @rocket.chat/fuselage-ui-kit@7.0.0-rc.2 + - @rocket.chat/gazzodown@7.0.0-rc.2 + - @rocket.chat/model-typings@0.4.1-rc.2 + - @rocket.chat/ui-contexts@7.0.0-rc.2 + - @rocket.chat/server-cloud-communication@0.0.2 + - @rocket.chat/models@0.0.39-rc.2 + - @rocket.chat/ui-theming@0.1.2 + - @rocket.chat/ui-avatar@3.0.0-rc.2 + - @rocket.chat/ui-client@7.0.0-rc.2 + - @rocket.chat/ui-video-conf@7.0.0-rc.2 + - @rocket.chat/web-ui-registration@7.0.0-rc.2 + - @rocket.chat/instance-status@0.0.39-rc.2 +
+ +## 6.9.0-rc.1 + +### Patch Changes + +- Bump @rocket.chat/meteor version. + +- ([#32479](https://github.com/RocketChat/Rocket.Chat/pull/32479)) Executing a logout and login action in the same "tab/instance", some streams were not being recreated, causing countless types of bugs. + + PS: as a workaround reloading after logout or login in also solves the problem. + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/rest-typings@6.9.0-rc.1 + - @rocket.chat/api-client@0.1.33-rc.1 + - @rocket.chat/license@0.1.15-rc.1 + - @rocket.chat/omnichannel-services@0.1.15-rc.1 + - @rocket.chat/pdf-worker@0.0.39-rc.1 + - @rocket.chat/presence@0.1.15-rc.1 + - @rocket.chat/apps@0.0.6-rc.1 + - @rocket.chat/core-services@0.3.15-rc.1 + - @rocket.chat/cron@0.0.35-rc.1 + - @rocket.chat/fuselage-ui-kit@7.0.0-rc.1 + - @rocket.chat/gazzodown@7.0.0-rc.1 + - @rocket.chat/model-typings@0.4.1-rc.1 + - @rocket.chat/ui-contexts@7.0.0-rc.1 + - @rocket.chat/server-cloud-communication@0.0.2 + - @rocket.chat/models@0.0.39-rc.1 + - @rocket.chat/ui-theming@0.1.2 + - @rocket.chat/ui-avatar@3.0.0-rc.1 + - @rocket.chat/ui-client@7.0.0-rc.1 + - @rocket.chat/ui-video-conf@7.0.0-rc.1 + - @rocket.chat/web-ui-registration@7.0.0-rc.1 + - @rocket.chat/instance-status@0.0.39-rc.1 +
+ +## 6.9.0-rc.0 + +### Minor Changes + +- ([#31917](https://github.com/RocketChat/Rocket.Chat/pull/31917)) Introduced a tab layout to the users page and implemented a tab called "All" that lists all users. + +- ([#32439](https://github.com/RocketChat/Rocket.Chat/pull/32439)) Allow visitors & integrations to access downloaded files after a room has closed. This was a known limitation in our codebase, where visitors were only able to access uploaded files in a livechat conversation while the conversation was open. + +- ([#32233](https://github.com/RocketChat/Rocket.Chat/pull/32233)) Makes the triggers fired by the condition `after-guest-registration` persist on the livechat client, it will persist through reloads and pagination, only reseting when a conversation is closed (no changes were done on the agent side of the conversation) + +- ([#32193](https://github.com/RocketChat/Rocket.Chat/pull/32193)) Adds CheckOption to departments multi selects improving options visibility state + +- ([#32317](https://github.com/RocketChat/Rocket.Chat/pull/32317)) Replace the read receipt receipt indicator in order to improve the accessibility complience + +- ([#32341](https://github.com/RocketChat/Rocket.Chat/pull/32341)) Changes the scrollbar color in order to improve the contrast and accessibility compliance + +- ([#32298](https://github.com/RocketChat/Rocket.Chat/pull/32298)) Added "Rocket.Chat Cloud Workspace ID" to workspace statistics page + +### Patch Changes + +- ([#32393](https://github.com/RocketChat/Rocket.Chat/pull/32393)) Fixed an issue causing monitors to dissapear from a saved unit every time a user saved the item. This was caused by the UI not sending the correct \_id of the monitors that were already saved, and this caused the Backend to ignore them and remove from the list. + +- ([#31695](https://github.com/RocketChat/Rocket.Chat/pull/31695)) Fix an issue where read receipts menu item wasn't considering the enabled setting to be displayed + +- ([#32454](https://github.com/RocketChat/Rocket.Chat/pull/32454)) Fixes an issue not allowing override retention policy in channels + +- ([#32444](https://github.com/RocketChat/Rocket.Chat/pull/32444)) Fixed an issue that prevented CAS users from being merged with existing user data on login + +- ([#32289](https://github.com/RocketChat/Rocket.Chat/pull/32289)) Fixed a problem in how server was processing errors that was sending 2 ephemeral error messages when @all or @here were used while they were disabled via permissions + +- ([#32348](https://github.com/RocketChat/Rocket.Chat/pull/32348)) Fixed an issue where translations would fallback to english some of the times. + +- ([#32182](https://github.com/RocketChat/Rocket.Chat/pull/32182)) Fixed an issue with object storage settings that was not allowing admins to decide if files generated via "Export conversation" feature were being proxied through server or not. + +- ([#32311](https://github.com/RocketChat/Rocket.Chat/pull/32311)) Fixed multiple issues with PDF generation logic when a quoted message was too big to fit in one single page. This was causing an internal infinite loop within the library (as it tried to make it fit, failing and then trying to fit on next page where the same happened thus causing a loop). + The library was not able to break down some nested views and thus was trying to fit the whole quote on one single page. Logic was updated to allow wrapping of the contents when messages are quoted (so they can span multiple lines) and removed a bunch of unnecesary views from the code. +- ([#32364](https://github.com/RocketChat/Rocket.Chat/pull/32364)) Fixed issue with "Export room as file" feature (`rooms.export` endpoint) generating an empty export when given an invalid date + +- ([#32314](https://github.com/RocketChat/Rocket.Chat/pull/32314)) Fixed an issue on Users converter that was not returning the `statusText` property from users even when the typing indicated property existed. + +- ([#32391](https://github.com/RocketChat/Rocket.Chat/pull/32391)) Fixes link image preview not opening in gallery mode + +- ([#32318](https://github.com/RocketChat/Rocket.Chat/pull/32318)) Fixed error handling for files bigger than NATS max allowed payload. This should prevent PDFs from erroring out when generating from rooms that contain heavy images. + +- ([#32345](https://github.com/RocketChat/Rocket.Chat/pull/32345)) Replaces the burger menu with an appropriate button fixing the semantics and mismatching color + +- ([#32414](https://github.com/RocketChat/Rocket.Chat/pull/32414)) Fixes the missing spacing on don`t ask again checkbox inside modals + +- ([#32269](https://github.com/RocketChat/Rocket.Chat/pull/32269)) Fixed a bad behavior with the interaction between OTR system messages & trash collection. We use trash collection as a temporary storage that holds recently deleted items from some collections. Messages is one of those. This was causing "User joined OTR" messages to be viewable when querying the trash collection. + Since OTR messages are by definition private, code was updated to bypass trash collection when removing these special messages. + + Note: this only applies to these system messages. OTR user's messages are not stored on the database. + +- ([#32415](https://github.com/RocketChat/Rocket.Chat/pull/32415)) This fuselage`s bump fixes: + + - The message toolbar visibility on hover (Firefox ESR) + - `Bubble` missing font-family + + [more details](https://github.com/RocketChat/fuselage/releases/tag/%40rocket.chat%2Ffuselage%400.53.7) + +- ([#32398](https://github.com/RocketChat/Rocket.Chat/pull/32398)) Fixed issue with external users being able to reset their passwords even when the "Allow Password Change for OAuth Users" setting is disabled + +- ([#32284](https://github.com/RocketChat/Rocket.Chat/pull/32284)) fixed Engagement Dashboard and Device Management admin pages loading indefinitely + +- ([#32342](https://github.com/RocketChat/Rocket.Chat/pull/32342)) bump fuselage adding `AttachmentAuthorName` missing color token + +-
Updated dependencies [ff4e396416, bc50dd54a2, ad86761209, f83bd56cc5, 6205ef14f0, 724ba3a729, ee5cdfc367, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/i18n@0.4.0-rc.0 + - @rocket.chat/core-services@0.3.15-rc.0 + - @rocket.chat/omnichannel-services@0.1.15-rc.0 + - @rocket.chat/pdf-worker@0.0.39-rc.0 + - @rocket.chat/rest-typings@6.9.0-rc.0 + - @rocket.chat/fuselage-ui-kit@7.0.0-rc.0 + - @rocket.chat/ui-kit@0.34.0-rc.0 + - @rocket.chat/api-client@0.1.33-rc.0 + - @rocket.chat/license@0.1.15-rc.0 + - @rocket.chat/presence@0.1.15-rc.0 + - @rocket.chat/apps@0.0.6-rc.0 + - @rocket.chat/cron@0.0.35-rc.0 + - @rocket.chat/gazzodown@7.0.0-rc.0 + - @rocket.chat/model-typings@0.4.1-rc.0 + - @rocket.chat/ui-contexts@7.0.0-rc.0 + - @rocket.chat/web-ui-registration@7.0.0-rc.0 + - @rocket.chat/server-cloud-communication@0.0.2 + - @rocket.chat/models@0.0.39-rc.0 + - @rocket.chat/ui-theming@0.1.2 + - @rocket.chat/ui-avatar@3.0.0-rc.0 + - @rocket.chat/ui-client@7.0.0-rc.0 + - @rocket.chat/ui-video-conf@7.0.0-rc.0 + - @rocket.chat/instance-status@0.0.39-rc.0 +
+ ## 6.8.0 ### Minor Changes diff --git a/apps/meteor/app/api/server/lib/emailInbox.ts b/apps/meteor/app/api/server/lib/emailInbox.ts index 663459c7bc05..304d297261af 100644 --- a/apps/meteor/app/api/server/lib/emailInbox.ts +++ b/apps/meteor/app/api/server/lib/emailInbox.ts @@ -1,6 +1,8 @@ import type { IEmailInbox } from '@rocket.chat/core-typings'; import { EmailInbox, Users } from '@rocket.chat/models'; -import type { Filter, InsertOneResult, Sort, UpdateResult, WithId } from 'mongodb'; +import type { DeleteResult, Filter, InsertOneResult, Sort } from 'mongodb'; + +import { notifyOnEmailInboxChanged } from '../../../lib/server/lib/notifyListener'; export const findEmailInboxes = async ({ query = {}, @@ -34,33 +36,31 @@ export const findEmailInboxes = async ({ }; }; -export const findOneEmailInbox = async ({ _id }: { _id: string }): Promise => { - return EmailInbox.findOneById(_id); -}; export const insertOneEmailInbox = async ( userId: string, emailInboxParams: Pick, -): Promise>> => { +): Promise> => { const obj = { ...emailInboxParams, _createdAt: new Date(), _updatedAt: new Date(), _createdBy: await Users.findOneById(userId, { projection: { username: 1 } }), }; - return EmailInbox.insertOne(obj); + + const response = await EmailInbox.create(obj); + + if (response.insertedId) { + void notifyOnEmailInboxChanged({ _id: response.insertedId, ...obj }, 'inserted'); + } + + return response; }; export const updateEmailInbox = async ( emailInboxParams: Pick, -): Promise> | UpdateResult> => { +): Promise | null> => { const { _id, active, name, email, description, senderInfo, department, smtp, imap } = emailInboxParams; - const emailInbox = await findOneEmailInbox({ _id }); - - if (!emailInbox) { - throw new Error('error-invalid-email-inbox'); - } - const updateEmailInbox = { $set: { active, @@ -76,5 +76,29 @@ export const updateEmailInbox = async ( ...(department === 'All' && { $unset: { department: 1 as const } }), }; - return EmailInbox.updateOne({ _id }, updateEmailInbox); + const updatedResponse = await EmailInbox.updateById(_id, updateEmailInbox); + + if (!updatedResponse.value) { + throw new Error('error-invalid-email-inbox'); + } + + void notifyOnEmailInboxChanged( + { + ...updatedResponse.value, + ...(department === 'All' && { department: undefined }), + }, + 'updated', + ); + + return updatedResponse.value; +}; + +export const removeEmailInbox = async (emailInboxId: IEmailInbox['_id']): Promise => { + const removeResponse = await EmailInbox.removeById(emailInboxId); + + if (removeResponse.deletedCount) { + void notifyOnEmailInboxChanged({ _id: emailInboxId }, 'removed'); + } + + return removeResponse; }; diff --git a/apps/meteor/app/api/server/v1/banners.ts b/apps/meteor/app/api/server/v1/banners.ts index 4dc74208153b..48c94d3711bd 100644 --- a/apps/meteor/app/api/server/v1/banners.ts +++ b/apps/meteor/app/api/server/v1/banners.ts @@ -52,9 +52,8 @@ import { API } from '../api'; */ API.v1.addRoute( 'banners.getNew', - { authRequired: true }, + { authRequired: true, deprecation: { version: '8.0.0', alternatives: ['banners/:id', 'banners'] } }, { - // deprecated async get() { check( this.queryParams, diff --git a/apps/meteor/app/api/server/v1/email-inbox.ts b/apps/meteor/app/api/server/v1/email-inbox.ts index 5748565a0f77..89ede496b78a 100644 --- a/apps/meteor/app/api/server/v1/email-inbox.ts +++ b/apps/meteor/app/api/server/v1/email-inbox.ts @@ -4,7 +4,7 @@ import { check, Match } from 'meteor/check'; import { sendTestEmailToInbox } from '../../../../server/features/EmailInbox/EmailInbox_Outgoing'; import { API } from '../api'; import { getPaginationItems } from '../helpers/getPaginationItems'; -import { insertOneEmailInbox, findEmailInboxes, findOneEmailInbox, updateEmailInbox } from '../lib/emailInbox'; +import { insertOneEmailInbox, findEmailInboxes, updateEmailInbox, removeEmailInbox } from '../lib/emailInbox'; API.v1.addRoute( 'email-inbox.list', @@ -55,12 +55,23 @@ API.v1.addRoute( let _id: string; if (!emailInboxParams?._id) { - const emailInbox = await insertOneEmailInbox(this.userId, emailInboxParams); - _id = emailInbox.insertedId.toString(); + const { insertedId } = await insertOneEmailInbox(this.userId, emailInboxParams); + + if (!insertedId) { + return API.v1.failure('Failed to create email inbox'); + } + + _id = insertedId; } else { - _id = emailInboxParams._id; - await updateEmailInbox({ ...emailInboxParams, _id }); + const emailInbox = await updateEmailInbox({ ...emailInboxParams, _id: emailInboxParams._id }); + + if (!emailInbox?._id) { + return API.v1.failure('Failed to update email inbox'); + } + + _id = emailInbox._id; } + return API.v1.success({ _id }); }, }, @@ -79,7 +90,7 @@ API.v1.addRoute( if (!_id) { throw new Error('error-invalid-param'); } - const emailInbox = await findOneEmailInbox({ _id }); + const emailInbox = await EmailInbox.findOneById(_id); if (!emailInbox) { return API.v1.notFound(); @@ -97,11 +108,12 @@ API.v1.addRoute( throw new Error('error-invalid-param'); } - const emailInboxes = await EmailInbox.findOneById(_id); - if (!emailInboxes) { + const { deletedCount } = await removeEmailInbox(_id); + + if (!deletedCount) { return API.v1.notFound(); } - await EmailInbox.removeById(_id); + return API.v1.success({ _id }); }, }, @@ -120,7 +132,7 @@ API.v1.addRoute( // TODO: Chapter day backend - check if user has permission to view this email inbox instead of null values // TODO: Chapter day: Remove this endpoint and move search to GET /email-inbox - const emailInbox = await EmailInbox.findOne({ email }); + const emailInbox = await EmailInbox.findByEmail(email); return API.v1.success({ emailInbox }); }, @@ -140,7 +152,7 @@ API.v1.addRoute( if (!_id) { throw new Error('error-invalid-param'); } - const emailInbox = await findOneEmailInbox({ _id }); + const emailInbox = await EmailInbox.findOneById(_id); if (!emailInbox) { return API.v1.notFound(); diff --git a/apps/meteor/app/authorization/server/functions/canDeleteMessage.ts b/apps/meteor/app/authorization/server/functions/canDeleteMessage.ts index 91769e71270a..7cd953a52bb2 100644 --- a/apps/meteor/app/authorization/server/functions/canDeleteMessage.ts +++ b/apps/meteor/app/authorization/server/functions/canDeleteMessage.ts @@ -34,7 +34,7 @@ export const canDeleteMessageAsync = async ( if (!allowed) { return false; } - const bypassBlockTimeLimit = await hasPermissionAsync(uid, 'bypass-time-limit-edit-and-delete'); + const bypassBlockTimeLimit = await hasPermissionAsync(uid, 'bypass-time-limit-edit-and-delete', rid); if (!bypassBlockTimeLimit) { const blockDeleteInMinutes = await getValue('Message_AllowDeleting_BlockDeleteInMinutes'); diff --git a/apps/meteor/app/file-upload/server/config/AmazonS3.ts b/apps/meteor/app/file-upload/server/config/AmazonS3.ts index 567e5e5d71eb..0f551d3b90d1 100644 --- a/apps/meteor/app/file-upload/server/config/AmazonS3.ts +++ b/apps/meteor/app/file-upload/server/config/AmazonS3.ts @@ -1,6 +1,5 @@ import http from 'http'; import https from 'https'; -import URL from 'url'; import _ from 'underscore'; @@ -8,12 +7,12 @@ import { settings } from '../../../settings/server'; import type { S3Options } from '../../ufs/AmazonS3/server'; import { FileUploadClass, FileUpload } from '../lib/FileUpload'; import '../../ufs/AmazonS3/server'; +import { forceDownload } from './helper'; const get: FileUploadClass['get'] = async function (this: FileUploadClass, file, req, res) { - const { query } = URL.parse(req.url || '', true); - const forceDownload = typeof query.download !== 'undefined'; + const forcedDownload = forceDownload(req); - const fileUrl = await this.store.getRedirectURL(file, forceDownload); + const fileUrl = await this.store.getRedirectURL(file, forcedDownload); if (!fileUrl || !file.store) { res.end(); return; @@ -23,7 +22,7 @@ const get: FileUploadClass['get'] = async function (this: FileUploadClass, file, if (settings.get(`FileUpload_S3_Proxy_${storeType}`)) { const request = /^https:/.test(fileUrl) ? https : http; - FileUpload.proxyFile(file.name || '', fileUrl, forceDownload, request, req, res); + FileUpload.proxyFile(file.name || '', fileUrl, forcedDownload, request, req, res); return; } diff --git a/apps/meteor/app/file-upload/server/config/FileSystem.ts b/apps/meteor/app/file-upload/server/config/FileSystem.ts index 98342daf2e46..75fdb5afc8ae 100644 --- a/apps/meteor/app/file-upload/server/config/FileSystem.ts +++ b/apps/meteor/app/file-upload/server/config/FileSystem.ts @@ -4,6 +4,7 @@ import { UploadFS } from '../../../../server/ufs'; import { settings } from '../../../settings/server'; import { FileUploadClass, FileUpload } from '../lib/FileUpload'; import { getFileRange, setRangeHeaders } from '../lib/ranges'; +import { getContentDisposition } from './helper'; const FileSystemUploads = new FileUploadClass({ name: 'FileSystem:Uploads', @@ -26,7 +27,8 @@ const FileSystemUploads = new FileUploadClass({ } file = FileUpload.addExtensionTo(file); - res.setHeader('Content-Disposition', `attachment; filename*=UTF-8''${encodeURIComponent(file.name || '')}`); + + res.setHeader('Content-Disposition', `${getContentDisposition(req)}; filename*=UTF-8''${encodeURIComponent(file.name || '')}`); file.uploadedAt && res.setHeader('Last-Modified', file.uploadedAt.toUTCString()); res.setHeader('Content-Type', file.type || 'application/octet-stream'); diff --git a/apps/meteor/app/file-upload/server/config/GoogleStorage.ts b/apps/meteor/app/file-upload/server/config/GoogleStorage.ts index 41eb4350b876..8fb901b5a123 100644 --- a/apps/meteor/app/file-upload/server/config/GoogleStorage.ts +++ b/apps/meteor/app/file-upload/server/config/GoogleStorage.ts @@ -1,18 +1,17 @@ import http from 'http'; import https from 'https'; -import URL from 'url'; import _ from 'underscore'; import { settings } from '../../../settings/server'; import { FileUploadClass, FileUpload } from '../lib/FileUpload'; import '../../ufs/GoogleStorage/server'; +import { forceDownload } from './helper'; const get: FileUploadClass['get'] = async function (this: FileUploadClass, file, req, res) { - const { query } = URL.parse(req.url || '', true); - const forceDownload = typeof query.download !== 'undefined'; + const forcedDownload = forceDownload(req); - const fileUrl = await this.store.getRedirectURL(file, forceDownload); + const fileUrl = await this.store.getRedirectURL(file, forcedDownload); if (!fileUrl || !file.store) { res.end(); return; @@ -22,7 +21,7 @@ const get: FileUploadClass['get'] = async function (this: FileUploadClass, file, if (settings.get(`FileUpload_GoogleStorage_Proxy_${storeType}`)) { const request = /^https:/.test(fileUrl) ? https : http; - FileUpload.proxyFile(file.name || '', fileUrl, forceDownload, request, req, res); + FileUpload.proxyFile(file.name || '', fileUrl, forcedDownload, request, req, res); return; } diff --git a/apps/meteor/app/file-upload/server/config/GridFS.ts b/apps/meteor/app/file-upload/server/config/GridFS.ts index 629d177581bf..3bb5f806f3a7 100644 --- a/apps/meteor/app/file-upload/server/config/GridFS.ts +++ b/apps/meteor/app/file-upload/server/config/GridFS.ts @@ -9,6 +9,7 @@ import { Logger } from '@rocket.chat/logger'; import { UploadFS } from '../../../../server/ufs'; import { FileUploadClass, FileUpload } from '../lib/FileUpload'; import { getFileRange, setRangeHeaders } from '../lib/ranges'; +import { getContentDisposition } from './helper'; const logger = new Logger('FileUpload'); @@ -161,7 +162,7 @@ new FileUploadClass({ async get(file, req, res) { file = FileUpload.addExtensionTo(file); - res.setHeader('Content-Disposition', `attachment; filename*=UTF-8''${encodeURIComponent(file.name || '')}`); + res.setHeader('Content-Disposition', `${getContentDisposition(req)}; filename*=UTF-8''${encodeURIComponent(file.name || '')}`); file.uploadedAt && res.setHeader('Last-Modified', file.uploadedAt.toUTCString()); res.setHeader('Content-Type', file.type || 'application/octet-stream'); res.setHeader('Content-Length', file.size || 0); diff --git a/apps/meteor/app/file-upload/server/config/helper.ts b/apps/meteor/app/file-upload/server/config/helper.ts new file mode 100644 index 000000000000..f1c465537255 --- /dev/null +++ b/apps/meteor/app/file-upload/server/config/helper.ts @@ -0,0 +1,21 @@ +import type http from 'http'; +import URL from 'url'; + +export const forceDownload = (req: http.IncomingMessage): boolean => { + const { query } = URL.parse(req.url || '', true); + + const forceDownload = typeof query.download !== 'undefined'; + if (forceDownload) { + return true; + } + + return query.contentDisposition === 'attachment'; +}; + +export const getContentDisposition = (req: http.IncomingMessage): string => { + const { query } = URL.parse(req.url || '', true); + if (query.contentDisposition === 'inline') { + return 'inline'; + } + return 'attachment'; +}; diff --git a/apps/meteor/app/integrations/server/lib/updateHistory.ts b/apps/meteor/app/integrations/server/lib/updateHistory.ts index ed304403e8c7..e8068ad82ac1 100644 --- a/apps/meteor/app/integrations/server/lib/updateHistory.ts +++ b/apps/meteor/app/integrations/server/lib/updateHistory.ts @@ -1,8 +1,8 @@ import type { IIntegrationHistory, OutgoingIntegrationEvent, IIntegration, IMessage, AtLeast } from '@rocket.chat/core-typings'; import { IntegrationHistory } from '@rocket.chat/models'; -import { Random } from '@rocket.chat/random'; import { omit } from '../../../../lib/utils/omit'; +import { notifyOnIntegrationHistoryChangedById, notifyOnIntegrationHistoryChanged } from '../../../lib/server/lib/notifyListener'; export const updateHistory = async ({ historyId, @@ -77,7 +77,12 @@ export const updateHistory = async ({ }; if (historyId) { - await IntegrationHistory.updateOne({ _id: historyId }, { $set: history }); + // Projecting just integration field to comply with existing listener behaviour + const integrationHistory = await IntegrationHistory.updateById(historyId, history, { projection: { 'integration._id': 1 } }); + if (!integrationHistory) { + throw new Error('error-updating-integration-history'); + } + void notifyOnIntegrationHistoryChanged(integrationHistory, 'updated', history); return historyId; } @@ -86,11 +91,15 @@ export const updateHistory = async ({ throw new Error('error-invalid-integration'); } - history._createdAt = new Date(); + // TODO: Had to force type cast here because of function's signature + // It would be easier if we separate into create and update functions + const { insertedId } = await IntegrationHistory.create(history as IIntegrationHistory); - const _id = Random.id(); + if (!insertedId) { + throw new Error('error-creating-integration-history'); + } - await IntegrationHistory.insertOne({ _id, ...history } as IIntegrationHistory); + void notifyOnIntegrationHistoryChangedById(insertedId, 'inserted'); - return _id; + return insertedId; }; diff --git a/apps/meteor/app/integrations/server/methods/clearIntegrationHistory.ts b/apps/meteor/app/integrations/server/methods/clearIntegrationHistory.ts index 2447683bd291..5b8f13ef1a3a 100644 --- a/apps/meteor/app/integrations/server/methods/clearIntegrationHistory.ts +++ b/apps/meteor/app/integrations/server/methods/clearIntegrationHistory.ts @@ -41,6 +41,7 @@ Meteor.methods({ }); } + // Don't sending to IntegrationHistory listener since it don't waits for 'removed' events. await IntegrationHistory.removeByIntegrationId(integrationId); notifications.streamIntegrationHistory.emit(integrationId, { type: 'removed', id: integrationId }); diff --git a/apps/meteor/app/integrations/server/methods/outgoing/deleteOutgoingIntegration.ts b/apps/meteor/app/integrations/server/methods/outgoing/deleteOutgoingIntegration.ts index cc3d138c554a..c9f2211d835b 100644 --- a/apps/meteor/app/integrations/server/methods/outgoing/deleteOutgoingIntegration.ts +++ b/apps/meteor/app/integrations/server/methods/outgoing/deleteOutgoingIntegration.ts @@ -41,6 +41,7 @@ export const deleteOutgoingIntegration = async (integrationId: string, userId: s } await Integrations.removeById(integrationId); + // Don't sending to IntegrationHistory listener since it don't waits for 'removed' events. await IntegrationHistory.removeByIntegrationId(integrationId); void notifyOnIntegrationChangedById(integrationId, 'removed'); }; diff --git a/apps/meteor/app/lib/server/functions/deleteUser.ts b/apps/meteor/app/lib/server/functions/deleteUser.ts index 3af123a72bf7..f2ca72a1d57d 100644 --- a/apps/meteor/app/lib/server/functions/deleteUser.ts +++ b/apps/meteor/app/lib/server/functions/deleteUser.ts @@ -19,7 +19,7 @@ import { callbacks } from '../../../../lib/callbacks'; import { i18n } from '../../../../server/lib/i18n'; import { FileUpload } from '../../../file-upload/server'; import { settings } from '../../../settings/server'; -import { notifyOnRoomChangedById, notifyOnIntegrationChangedByUserId } from '../lib/notifyListener'; +import { notifyOnRoomChangedById, notifyOnIntegrationChangedByUserId, notifyOnLivechatDepartmentAgentChanged } from '../lib/notifyListener'; import { getSubscribedRoomsForUserWithDetails, shouldRemoveOrChangeOwner } from './getRoomsWithSingleOwner'; import { getUserSingleOwnedRooms } from './getUserSingleOwnedRooms'; import { relinquishRoomOwnerships } from './relinquishRoomOwnerships'; @@ -95,9 +95,24 @@ export async function deleteUser(userId: string, confirmRelinquish = false, dele await Subscriptions.removeByUserId(userId); // Remove user subscriptions + // Remove user as livechat agent if (user.roles.includes('livechat-agent')) { - // Remove user as livechat agent - await LivechatDepartmentAgents.removeByAgentId(userId); + const departmentAgents = await LivechatDepartmentAgents.findByAgentId(userId).toArray(); + + const { deletedCount } = await LivechatDepartmentAgents.removeByAgentId(userId); + + if (deletedCount > 0) { + departmentAgents.forEach((depAgent) => { + void notifyOnLivechatDepartmentAgentChanged( + { + _id: depAgent._id, + agentId: userId, + departmentId: depAgent.departmentId, + }, + 'removed', + ); + }); + } } if (user.roles.includes('livechat-monitor')) { diff --git a/apps/meteor/app/lib/server/functions/saveUser.js b/apps/meteor/app/lib/server/functions/saveUser.js index 3a2808b4171c..e11e68f99ab0 100644 --- a/apps/meteor/app/lib/server/functions/saveUser.js +++ b/apps/meteor/app/lib/server/functions/saveUser.js @@ -401,6 +401,7 @@ export const saveUser = async function (userId, userData) { const updateUser = { $set: {}, + $unset: {}, }; handleBio(updateUser, userData.bio); @@ -419,6 +420,9 @@ export const saveUser = async function (userId, userData) { if (typeof userData.requirePasswordChange !== 'undefined') { updateUser.$set.requirePasswordChange = userData.requirePasswordChange; + if (!userData.requirePasswordChange) { + updateUser.$unset.requirePasswordChangeReason = 1; + } } if (typeof userData.verified === 'boolean') { diff --git a/apps/meteor/app/lib/server/lib/notifyListener.ts b/apps/meteor/app/lib/server/lib/notifyListener.ts index c019eba0db7a..8ba5f45c4ae7 100644 --- a/apps/meteor/app/lib/server/lib/notifyListener.ts +++ b/apps/meteor/app/lib/server/lib/notifyListener.ts @@ -10,8 +10,22 @@ import type { IPbxEvent, LoginServiceConfiguration as LoginServiceConfigurationData, ILivechatPriority, + ILivechatDepartmentAgents, + IEmailInbox, + IIntegrationHistory, + AtLeast, } from '@rocket.chat/core-typings'; -import { Rooms, Permissions, Settings, PbxEvents, Roles, Integrations, LoginServiceConfiguration } from '@rocket.chat/models'; +import { + Rooms, + Permissions, + Settings, + PbxEvents, + Roles, + Integrations, + LoginServiceConfiguration, + IntegrationHistory, + LivechatDepartmentAgents, +} from '@rocket.chat/models'; type ClientAction = 'inserted' | 'updated' | 'removed'; @@ -254,3 +268,88 @@ export async function notifyOnIntegrationChangedByChannels( + data: Pick | T, // TODO: improve typing + clientAction: ClientAction = 'updated', +): Promise { + if (!dbWatchersDisabled) { + return; + } + + void api.broadcast('watch.emailInbox', { clientAction, id: data._id, data }); +} + +export async function notifyOnIntegrationHistoryChanged( + data: AtLeast, + clientAction: ClientAction = 'updated', + diff: Partial = {}, +): Promise { + if (!dbWatchersDisabled) { + return; + } + + void api.broadcast('watch.integrationHistory', { clientAction, id: data._id, data, diff }); +} + +export async function notifyOnIntegrationHistoryChangedById( + id: T['_id'], + clientAction: ClientAction = 'updated', + diff: Partial = {}, +): Promise { + if (!dbWatchersDisabled) { + return; + } + + const item = await IntegrationHistory.findOneById(id); + + if (!item) { + return; + } + + void api.broadcast('watch.integrationHistory', { clientAction, id: item._id, data: item, diff }); +} + +export async function notifyOnLivechatDepartmentAgentChanged( + data: Partial & Pick, + clientAction: ClientAction = 'updated', +): Promise { + if (!dbWatchersDisabled) { + return; + } + + void api.broadcast('watch.livechatDepartmentAgents', { clientAction, id: data._id, data }); +} + +export async function notifyOnLivechatDepartmentAgentChangedByDepartmentId( + departmentId: T['departmentId'], + clientAction: 'inserted' | 'updated' = 'updated', +): Promise { + if (!dbWatchersDisabled) { + return; + } + + const items = LivechatDepartmentAgents.findByDepartmentId(departmentId, { projection: { _id: 1, agentId: 1, departmentId: 1 } }); + + for await (const item of items) { + void api.broadcast('watch.livechatDepartmentAgents', { clientAction, id: item._id, data: item }); + } +} + +export async function notifyOnLivechatDepartmentAgentChangedByAgentsAndDepartmentId( + agentsIds: T['agentId'][], + departmentId: T['departmentId'], + clientAction: 'inserted' | 'updated' = 'updated', +): Promise { + if (!dbWatchersDisabled) { + return; + } + + const items = LivechatDepartmentAgents.findByAgentsAndDepartmentId(agentsIds, departmentId, { + projection: { _id: 1, agentId: 1, departmentId: 1 }, + }); + + for await (const item of items) { + void api.broadcast('watch.livechatDepartmentAgents', { clientAction, id: item._id, data: item }); + } +} diff --git a/apps/meteor/app/lib/server/methods/updateMessage.ts b/apps/meteor/app/lib/server/methods/updateMessage.ts index 277841fd58e7..470fe0760b6d 100644 --- a/apps/meteor/app/lib/server/methods/updateMessage.ts +++ b/apps/meteor/app/lib/server/methods/updateMessage.ts @@ -53,7 +53,7 @@ export async function executeUpdateMessage(uid: IUser['_id'], message: AtLeast { - const departmentIds = (await LivechatDepartmentAgents.findByAgentId(agent._id).toArray()).map((department) => department.departmentId); - await Promise.all([ + const departments = await LivechatDepartmentAgents.findByAgentId(agent._id).toArray(); + + const [, { deletedCount }] = await Promise.all([ Users.removeAgent(agent._id), LivechatDepartmentAgents.removeByAgentId(agent._id), agent.username && LivechatVisitors.removeContactManagerByUsername(agent.username), - departmentIds.length && LivechatDepartment.decreaseNumberOfAgentsByIds(departmentIds), + departments.length && LivechatDepartment.decreaseNumberOfAgentsByIds(departments.map(({ departmentId }) => departmentId)), ]); + + if (deletedCount > 0) { + departments.forEach((depAgent) => { + void notifyOnLivechatDepartmentAgentChanged( + { + _id: depAgent._id, + agentId: agent._id, + departmentId: depAgent.departmentId, + }, + 'removed', + ); + }); + } }); diff --git a/apps/meteor/app/livechat/server/lib/Departments.ts b/apps/meteor/app/livechat/server/lib/Departments.ts index ed55a856e0b8..3dfa01e4f6b6 100644 --- a/apps/meteor/app/livechat/server/lib/Departments.ts +++ b/apps/meteor/app/livechat/server/lib/Departments.ts @@ -1,8 +1,9 @@ -import type { ILivechatDepartment, ILivechatDepartmentAgents } from '@rocket.chat/core-typings'; +import type { ILivechatDepartment } from '@rocket.chat/core-typings'; import { Logger } from '@rocket.chat/logger'; import { LivechatDepartment, LivechatDepartmentAgents, LivechatRooms } from '@rocket.chat/models'; import { callbacks } from '../../../../lib/callbacks'; +import { notifyOnLivechatDepartmentAgentChanged } from '../../../lib/server/lib/notifyListener'; class DepartmentHelperClass { logger = new Logger('Omnichannel:DepartmentHelper'); @@ -24,29 +25,42 @@ class DepartmentHelperClass { throw new Error('error-failed-to-delete-department'); } - const agentsIds: string[] = await LivechatDepartmentAgents.findAgentsByDepartmentId>( - department._id, - { projection: { agentId: 1 } }, - ) - .cursor.map((agent) => agent.agentId) - .toArray(); + const removedAgents = await LivechatDepartmentAgents.findByDepartmentId(department._id, { projection: { agentId: 1 } }).toArray(); this.logger.debug( `Performing post-department-removal actions: ${_id}. Removing department agents, unsetting fallback department and removing department from rooms`, ); + const removeByDept = LivechatDepartmentAgents.removeByDepartmentId(_id); + const promiseResponses = await Promise.allSettled([ - LivechatDepartmentAgents.removeByDepartmentId(_id), + removeByDept, LivechatDepartment.unsetFallbackDepartmentByDepartmentId(_id), LivechatRooms.bulkRemoveDepartmentAndUnitsFromRooms(_id), ]); + promiseResponses.forEach((response, index) => { if (response.status === 'rejected') { this.logger.error(`Error while performing post-department-removal actions: ${_id}. Action No: ${index}. Error:`, response.reason); } }); - await callbacks.run('livechat.afterRemoveDepartment', { department, agentsIds }); + const { deletedCount } = await removeByDept; + + if (deletedCount > 0) { + removedAgents.forEach(({ _id: docId, agentId }) => { + void notifyOnLivechatDepartmentAgentChanged( + { + _id: docId, + agentId, + departmentId: _id, + }, + 'removed', + ); + }); + } + + await callbacks.run('livechat.afterRemoveDepartment', { department, agentsIds: removedAgents.map(({ agentId }) => agentId) }); return ret; } diff --git a/apps/meteor/app/livechat/server/lib/Helper.ts b/apps/meteor/app/livechat/server/lib/Helper.ts index 453869d4425a..dacd99be00f9 100644 --- a/apps/meteor/app/livechat/server/lib/Helper.ts +++ b/apps/meteor/app/livechat/server/lib/Helper.ts @@ -37,6 +37,10 @@ import { i18n } from '../../../../server/lib/i18n'; import { hasRoleAsync } from '../../../authorization/server/functions/hasRole'; import { sendNotification } from '../../../lib/server'; import { sendMessage } from '../../../lib/server/functions/sendMessage'; +import { + notifyOnLivechatDepartmentAgentChanged, + notifyOnLivechatDepartmentAgentChangedByAgentsAndDepartmentId, +} from '../../../lib/server/lib/notifyListener'; import { settings } from '../../../settings/server'; import { Livechat as LivechatTyped } from './LivechatTyped'; import { queueInquiry, saveQueueInquiry } from './QueueManager'; @@ -697,14 +701,31 @@ export const updateDepartmentAgents = async ( }); const { upsert = [], remove = [] } = agents; - const agentsRemoved = []; + + const agentsUpdated = []; + const agentsRemoved = remove.map(({ agentId }: { agentId: string }) => agentId); const agentsAdded = []; - for await (const { agentId } of remove) { - await LivechatDepartmentAgents.removeByDepartmentIdAndAgentId(departmentId, agentId); - agentsRemoved.push(agentId); - } if (agentsRemoved.length > 0) { + const removedIds = await LivechatDepartmentAgents.findByAgentsAndDepartmentId(agentsRemoved, departmentId, { + projection: { agentId: 1 }, + }).toArray(); + + const { deletedCount } = await LivechatDepartmentAgents.removeByIds(removedIds.map(({ _id }) => _id)); + + if (deletedCount > 0) { + removedIds.forEach(({ _id, agentId }) => { + void notifyOnLivechatDepartmentAgentChanged( + { + _id, + agentId, + departmentId, + }, + 'removed', + ); + }); + } + callbacks.runAsync('livechat.removeAgentDepartment', { departmentId, agentsId: agentsRemoved }); } @@ -714,7 +735,7 @@ export const updateDepartmentAgents = async ( continue; } - await LivechatDepartmentAgents.saveAgent({ + const livechatDepartmentAgent = await LivechatDepartmentAgents.saveAgent({ agentId: agent.agentId, departmentId, username: agentFromDb.username || '', @@ -722,6 +743,20 @@ export const updateDepartmentAgents = async ( order: agent.order ? parseFromIntOrStr(agent.order) : 0, departmentEnabled, }); + + if (livechatDepartmentAgent.upsertedId) { + void notifyOnLivechatDepartmentAgentChanged( + { + _id: livechatDepartmentAgent.upsertedId as any, + agentId: agent.agentId, + departmentId, + }, + 'inserted', + ); + } else { + agentsUpdated.push(agent.agentId); + } + agentsAdded.push(agent.agentId); } @@ -732,6 +767,10 @@ export const updateDepartmentAgents = async ( }); } + if (agentsUpdated.length > 0) { + void notifyOnLivechatDepartmentAgentChangedByAgentsAndDepartmentId(agentsUpdated, departmentId); + } + if (agentsRemoved.length > 0 || agentsAdded.length > 0) { const numAgents = await LivechatDepartmentAgents.countByDepartmentId(departmentId); await LivechatDepartment.updateNumAgentsById(departmentId, numAgents); diff --git a/apps/meteor/app/livechat/server/lib/LivechatTyped.ts b/apps/meteor/app/livechat/server/lib/LivechatTyped.ts index 8af9980eb5e6..27d9b4b9bdae 100644 --- a/apps/meteor/app/livechat/server/lib/LivechatTyped.ts +++ b/apps/meteor/app/livechat/server/lib/LivechatTyped.ts @@ -57,7 +57,7 @@ import { FileUpload } from '../../../file-upload/server'; import { deleteMessage } from '../../../lib/server/functions/deleteMessage'; import { sendMessage } from '../../../lib/server/functions/sendMessage'; import { updateMessage } from '../../../lib/server/functions/updateMessage'; -import { notifyOnRoomChangedById } from '../../../lib/server/lib/notifyListener'; +import { notifyOnLivechatDepartmentAgentChangedByDepartmentId, notifyOnRoomChangedById } from '../../../lib/server/lib/notifyListener'; import * as Mailer from '../../../mailer/server/api'; import { metrics } from '../../../metrics/server'; import { settings } from '../../../settings/server'; @@ -1002,6 +1002,8 @@ class LivechatClass { await Promise.all([LivechatDepartmentAgents.disableAgentsByDepartmentId(_id), LivechatDepartment.archiveDepartment(_id)]); + void notifyOnLivechatDepartmentAgentChangedByDepartmentId(_id); + await callbacks.run('livechat.afterDepartmentArchived', department); } @@ -1014,6 +1016,9 @@ class LivechatClass { // TODO: these kind of actions should be on events instead of here await Promise.all([LivechatDepartmentAgents.enableAgentsByDepartmentId(_id), LivechatDepartment.unarchiveDepartment(_id)]); + + void notifyOnLivechatDepartmentAgentChangedByDepartmentId(_id); + return true; } diff --git a/apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts b/apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts index f3cf0be67ca9..589c387772fb 100644 --- a/apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts +++ b/apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts @@ -185,7 +185,7 @@ Meteor.startup(async () => { return false; } const blockEditInMinutes = settings.Message_AllowEditing_BlockEditInMinutes as number; - const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-delete'); + const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-delete', message.rid); if (!bypassBlockTimeLimit && blockEditInMinutes) { let msgTs; diff --git a/apps/meteor/app/utils/rocketchat.info b/apps/meteor/app/utils/rocketchat.info index 5878bf0b3190..b10a632463e7 100644 --- a/apps/meteor/app/utils/rocketchat.info +++ b/apps/meteor/app/utils/rocketchat.info @@ -1,3 +1,3 @@ { - "version": "6.9.0-develop" + "version": "6.10.0-develop" } diff --git a/apps/meteor/client/components/ImageGallery/ImageGallery.tsx b/apps/meteor/client/components/ImageGallery/ImageGallery.tsx index 8f4f76a14afb..0fb31c5a2560 100644 --- a/apps/meteor/client/components/ImageGallery/ImageGallery.tsx +++ b/apps/meteor/client/components/ImageGallery/ImageGallery.tsx @@ -112,6 +112,7 @@ export const ImageGallery = ({ images, onClose, loadMore }: { images: IUpload[]; const swiperRef = useRef(null); const [, setSwiperInst] = useState(); const [zoomScale, setZoomScale] = useState(1); + const [gridSize, setGridSize] = useState(images.length); const handleZoom = (ratio: number) => { if (swiperRef.current?.swiper.zoom) { @@ -174,15 +175,20 @@ export const ImageGallery = ({ images, onClose, loadMore }: { images: IUpload[]; onKeyPress={(_, keyCode) => String(keyCode) === '27' && onClose()} modules={[Navigation, Zoom, Keyboard, A11y]} onInit={(swiper) => setSwiperInst(swiper)} - onReachEnd={loadMore} + onSlidesGridLengthChange={(swiper) => { + swiper.slideTo(images.length - gridSize, 2000); + setGridSize(images.length); + }} + onReachBeginning={loadMore} + initialSlide={images.length - 1} > - {images?.map(({ _id, url }) => ( + {[...images].reverse().map(({ _id, url }) => (
{/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions, - jsx-a11y/click-events-have-key-events - */} + jsx-a11y/click-events-have-key-events + */}
diff --git a/apps/meteor/client/components/message/ReadReceiptIndicator.tsx b/apps/meteor/client/components/message/ReadReceiptIndicator.tsx index 90b3bb52c995..ac8ae925fbe5 100644 --- a/apps/meteor/client/components/message/ReadReceiptIndicator.tsx +++ b/apps/meteor/client/components/message/ReadReceiptIndicator.tsx @@ -21,7 +21,7 @@ const ReadReceiptIndicator = ({ mid, unread }: ReadReceiptIndicatorProps): React insetBlockStart={2} insetInlineEnd={8} > - + ); }; diff --git a/apps/meteor/client/components/message/content/attachments/file/GenericFileAttachment.tsx b/apps/meteor/client/components/message/content/attachments/file/GenericFileAttachment.tsx index 4301520c6173..3bbf1ccdc115 100644 --- a/apps/meteor/client/components/message/content/attachments/file/GenericFileAttachment.tsx +++ b/apps/meteor/client/components/message/content/attachments/file/GenericFileAttachment.tsx @@ -35,7 +35,7 @@ const GenericFileAttachment = ({ const handleTitleClick = (event: UIEvent): void => { if (openDocumentViewer && link && format === 'PDF') { event.preventDefault(); - openDocumentViewer(getURL(link), format, ''); + openDocumentViewer(`${getURL(link)}?contentDisposition=inline`, format, ''); } }; @@ -55,7 +55,12 @@ const GenericFileAttachment = ({ } > - + {title} {size && ( diff --git a/apps/meteor/client/lib/chats/data.ts b/apps/meteor/client/lib/chats/data.ts index f2c049ad04b1..12fb4097dce5 100644 --- a/apps/meteor/client/lib/chats/data.ts +++ b/apps/meteor/client/lib/chats/data.ts @@ -95,7 +95,7 @@ export const createDataAPI = ({ rid, tmid }: { rid: IRoom['_id']; tmid: IMessage } const blockEditInMinutes = settings.get('Message_AllowEditing_BlockEditInMinutes') as number | undefined; - const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-delete'); + const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-delete', message.rid); const elapsedMinutes = moment().diff(message.ts, 'minutes'); if (!bypassBlockTimeLimit && elapsedMinutes && blockEditInMinutes && elapsedMinutes > blockEditInMinutes) { @@ -208,7 +208,7 @@ export const createDataAPI = ({ rid, tmid }: { rid: IRoom['_id']; tmid: IMessage } const blockDeleteInMinutes = settings.get('Message_AllowDeleting_BlockDeleteInMinutes') as number | undefined; - const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-delete'); + const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-delete', message.rid); const elapsedMinutes = moment().diff(message.ts, 'minutes'); const onTimeForDelete = bypassBlockTimeLimit || !blockDeleteInMinutes || !elapsedMinutes || elapsedMinutes <= blockDeleteInMinutes; diff --git a/apps/meteor/client/methods/updateMessage.ts b/apps/meteor/client/methods/updateMessage.ts index deb2878072c5..719a036f870c 100644 --- a/apps/meteor/client/methods/updateMessage.ts +++ b/apps/meteor/client/methods/updateMessage.ts @@ -50,7 +50,7 @@ Meteor.methods({ } const blockEditInMinutes = Number(settings.get('Message_AllowEditing_BlockEditInMinutes') as number | undefined); - const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-delete'); + const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-delete', message.rid); if (!bypassBlockTimeLimit && blockEditInMinutes !== 0) { if (originalMessage.ts) { diff --git a/apps/meteor/client/providers/AppsProvider/AppsProvider.spec.ts b/apps/meteor/client/providers/AppsProvider/AppsProvider.spec.ts new file mode 100644 index 000000000000..8210fe22eec5 --- /dev/null +++ b/apps/meteor/client/providers/AppsProvider/AppsProvider.spec.ts @@ -0,0 +1,39 @@ +import type { App } from '@rocket.chat/core-typings'; +import type { UseQueryResult } from '@tanstack/react-query'; + +import { createFakeApp } from '../../../tests/mocks/data'; +import { createFakeAppInstalledMarketplace, createFakeAppPrivate } from '../../../tests/mocks/data/marketplace'; +import { storeQueryFunction } from './storeQueryFunction'; + +describe(`when an app installed from the Marketplace, but has since been unpublished`, () => { + it(`should still be present in the installed app data provided`, () => { + const marketplaceMockQuery = { + data: [createFakeApp({ id: 'marketplace-1' }), createFakeAppInstalledMarketplace({ id: 'marketplace-2' })], + isFetched: true, + } as unknown as UseQueryResult; + + const instanceMockQuery = { + data: [ + marketplaceMockQuery.data?.[1], + createFakeAppInstalledMarketplace({ id: 'marketplace-3' }), // This app has been installed via Marketplace but has been unpublished since + createFakeAppPrivate({ id: 'private-1' }), + ], + isFetched: true, + } as unknown as UseQueryResult; + + const [marketplaceList, installedList, privateList] = storeQueryFunction(marketplaceMockQuery, instanceMockQuery); + + expect(marketplaceList.find((app) => app.id === 'marketplace-1')).toBeTruthy(); + expect(marketplaceList.find((app) => app.id === 'marketplace-2')).toBeTruthy(); + expect(marketplaceList.find((app) => app.id === 'marketplace-3')).toBeUndefined(); + expect(marketplaceList).toHaveLength(2); + + expect(installedList.find((app) => app.id === 'marketplace-1')).toBeUndefined(); + expect(installedList.find((app) => app.id === 'marketplace-2')).toBeTruthy(); + expect(installedList.find((app) => app.id === 'marketplace-3')).toBeTruthy(); + expect(installedList).toHaveLength(2); + + expect(privateList.find((app) => app.id === 'private-1')).toBeTruthy(); + expect(privateList).toHaveLength(1); + }); +}); diff --git a/apps/meteor/client/providers/AppsProvider.tsx b/apps/meteor/client/providers/AppsProvider/AppsProvider.tsx similarity index 58% rename from apps/meteor/client/providers/AppsProvider.tsx rename to apps/meteor/client/providers/AppsProvider/AppsProvider.tsx index 905302b7ce4d..cf1d4d671d94 100644 --- a/apps/meteor/client/providers/AppsProvider.tsx +++ b/apps/meteor/client/providers/AppsProvider/AppsProvider.tsx @@ -4,16 +4,15 @@ import { useQuery, useQueryClient } from '@tanstack/react-query'; import type { ReactNode } from 'react'; import React, { useEffect } from 'react'; -import { AppClientOrchestratorInstance } from '../apps/orchestrator'; -import { AppsContext } from '../contexts/AppsContext'; -import { useIsEnterprise } from '../hooks/useIsEnterprise'; -import { useInvalidateLicense } from '../hooks/useLicense'; -import type { AsyncState } from '../lib/asyncState'; -import { AsyncStatePhase } from '../lib/asyncState'; -import { useInvalidateAppsCountQueryCallback } from '../views/marketplace/hooks/useAppsCountQuery'; -import type { App } from '../views/marketplace/types'; - -const sortByName = (apps: App[]): App[] => apps.sort((a, b) => (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1)); +import { AppClientOrchestratorInstance } from '../../apps/orchestrator'; +import { AppsContext } from '../../contexts/AppsContext'; +import { useIsEnterprise } from '../../hooks/useIsEnterprise'; +import { useInvalidateLicense } from '../../hooks/useLicense'; +import type { AsyncState } from '../../lib/asyncState'; +import { AsyncStatePhase } from '../../lib/asyncState'; +import { useInvalidateAppsCountQueryCallback } from '../../views/marketplace/hooks/useAppsCountQuery'; +import type { App } from '../../views/marketplace/types'; +import { storeQueryFunction } from './storeQueryFunction'; const getAppState = ( loading: boolean, @@ -96,60 +95,10 @@ const AppsProvider = ({ children }: AppsProviderProps) => { }, ); - const store = useQuery( - ['marketplace', 'apps-stored', instance.data, marketplace.data], - () => { - if (!marketplace.isFetched && !instance.isFetched) { - throw new Error('Apps not loaded'); - } - - const marketplaceApps: App[] = []; - const installedApps: App[] = []; - const privateApps: App[] = []; - const clonedData = [...(instance.data || [])]; - - sortByName(marketplace.data || []).forEach((app) => { - const appIndex = clonedData.findIndex(({ id }) => id === app.id); - const [installedApp] = appIndex > -1 ? clonedData.splice(appIndex, 1) : []; - - const record = { - ...app, - ...(installedApp && { - private: installedApp.private, - installed: true, - status: installedApp.status, - version: installedApp.version, - licenseValidation: installedApp.licenseValidation, - migrated: installedApp.migrated, - }), - bundledIn: app.bundledIn, - marketplaceVersion: app.version, - }; - - if (installedApp) { - if (installedApp.private) { - privateApps.push(record); - } else { - installedApps.push(record); - } - } - - marketplaceApps.push(record); - }); - - sortByName(clonedData).forEach((app) => { - if (app.private) { - privateApps.push(app); - } - }); - - return [marketplaceApps, installedApps, privateApps]; - }, - { - enabled: marketplace.isFetched && instance.isFetched, - keepPreviousData: true, - }, - ); + const store = useQuery(['marketplace', 'apps-stored', instance.data, marketplace.data], () => storeQueryFunction(marketplace, instance), { + enabled: marketplace.isFetched && instance.isFetched, + keepPreviousData: true, + }); const [marketplaceAppsData, installedAppsData, privateAppsData] = store.data || []; const { isLoading } = store; diff --git a/apps/meteor/client/providers/AppsProvider/index.ts b/apps/meteor/client/providers/AppsProvider/index.ts new file mode 100644 index 000000000000..94ae81e87e4c --- /dev/null +++ b/apps/meteor/client/providers/AppsProvider/index.ts @@ -0,0 +1,3 @@ +import AppsProvider from './AppsProvider'; + +export default AppsProvider; diff --git a/apps/meteor/client/providers/AppsProvider/storeQueryFunction.ts b/apps/meteor/client/providers/AppsProvider/storeQueryFunction.ts new file mode 100644 index 000000000000..a7c9d21f4df6 --- /dev/null +++ b/apps/meteor/client/providers/AppsProvider/storeQueryFunction.ts @@ -0,0 +1,64 @@ +import { type UseQueryResult } from '@tanstack/react-query'; + +import type { App } from '../../views/marketplace/types'; + +const sortByName = (apps: App[]): App[] => apps.sort((a, b) => (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1)); + +/** + * Aggregates result data from marketplace request and instance installed into their appropriate lists + * + * Exporting for better testing + */ +export function storeQueryFunction( + marketplace: UseQueryResult, + instance: UseQueryResult, +): [App[], App[], App[]] { + if (!marketplace.isFetched && !instance.isFetched) { + throw new Error('Apps not loaded'); + } + + const marketplaceApps: App[] = []; + const installedApps: App[] = []; + const privateApps: App[] = []; + const clonedData = [...(instance.data || [])]; + + sortByName(marketplace.data || []).forEach((app) => { + const appIndex = clonedData.findIndex(({ id }) => id === app.id); + const [installedApp] = appIndex > -1 ? clonedData.splice(appIndex, 1) : []; + + const record = { + ...app, + ...(installedApp && { + private: installedApp.private, + installed: true, + status: installedApp.status, + version: installedApp.version, + licenseValidation: installedApp.licenseValidation, + migrated: installedApp.migrated, + }), + bundledIn: app.bundledIn, + marketplaceVersion: app.version, + }; + + if (installedApp) { + if (installedApp.private) { + privateApps.push(record); + } else { + installedApps.push(record); + } + } + + marketplaceApps.push(record); + }); + + sortByName(clonedData).forEach((app) => { + if (app.private) { + privateApps.push(app); + return; + } + + installedApps.push(app); + }); + + return [marketplaceApps, installedApps, privateApps]; +} diff --git a/apps/meteor/client/sidebar/header/UserMenu.tsx b/apps/meteor/client/sidebar/header/UserMenu.tsx index a53836eda311..592fc19656e9 100644 --- a/apps/meteor/client/sidebar/header/UserMenu.tsx +++ b/apps/meteor/client/sidebar/header/UserMenu.tsx @@ -28,6 +28,7 @@ const UserMenu = ({ user }: { user: IUser }) => { selectionMode='multiple' sections={sections} title={t('User_menu')} + aria-label={t('User_menu')} onAction={handleAction} isOpen={isOpen} onOpenChange={setIsOpen} @@ -41,6 +42,7 @@ const UserMenu = ({ user }: { user: IUser }) => { selectionMode='multiple' sections={sections} title={t('User_menu')} + aria-label={t('User_menu')} onAction={handleAction} isOpen={isOpen} onOpenChange={setIsOpen} diff --git a/apps/meteor/client/startup/readReceipt.ts b/apps/meteor/client/startup/readReceipt.ts index 7caa9bf02b66..36eb50b6bcbd 100644 --- a/apps/meteor/client/startup/readReceipt.ts +++ b/apps/meteor/client/startup/readReceipt.ts @@ -17,7 +17,7 @@ Meteor.startup(() => { MessageAction.addButton({ id: 'receipt-detail', - icon: 'double-check', + icon: 'check-double', label: 'Read_Receipts', context: ['starred', 'message', 'message-mobile', 'threads', 'videoconf', 'videoconf-threads'], type: 'duplication', diff --git a/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRolePage.tsx b/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRolePage.tsx index 9c418c74c3bc..4bfb2afc81d3 100644 --- a/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRolePage.tsx +++ b/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRolePage.tsx @@ -1,9 +1,10 @@ import type { IRole, IRoom } from '@rocket.chat/core-typings'; -import { Box, Field, FieldLabel, FieldRow, Margins, ButtonGroup, Button, Callout } from '@rocket.chat/fuselage'; -import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; -import { useToastMessageDispatch, useRoute, useEndpoint, useTranslation } from '@rocket.chat/ui-contexts'; +import { Box, Field, FieldLabel, FieldRow, Margins, ButtonGroup, Button, Callout, FieldError } from '@rocket.chat/fuselage'; +import { useEffectEvent, useUniqueId } from '@rocket.chat/fuselage-hooks'; +import { useToastMessageDispatch, useEndpoint, useTranslation, useRouter } from '@rocket.chat/ui-contexts'; +import { useQueryClient } from '@tanstack/react-query'; import type { ReactElement } from 'react'; -import React, { useRef } from 'react'; +import React from 'react'; import { useForm, Controller } from 'react-hook-form'; import { Page, PageHeader, PageContent } from '../../../../components/Page'; @@ -18,42 +19,35 @@ type UsersInRolePayload = { const UsersInRolePage = ({ role }: { role: IRole }): ReactElement => { const t = useTranslation(); - const reload = useRef<() => void>(() => undefined); const dispatchToastMessage = useToastMessageDispatch(); + const queryClient = useQueryClient(); const { control, handleSubmit, - formState: { isDirty }, - reset, - getValues, + formState: { errors, isDirty }, + watch, } = useForm({ defaultValues: { users: [] } }); const { _id, name, description } = role; - const router = useRoute('admin-permissions'); - const addUser = useEndpoint('POST', '/v1/roles.addUserToRole'); + const router = useRouter(); + const addUserToRoleEndpoint = useEndpoint('POST', '/v1/roles.addUserToRole'); - const rid = getValues('rid'); + const { rid } = watch(); + const roomFieldId = useUniqueId(); + const usersFieldId = useUniqueId(); - const handleReturn = useMutableCallback(() => { - router.push({ - context: 'edit', - _id, - }); - }); - - const handleAdd = useMutableCallback(async ({ users, rid }: UsersInRolePayload) => { + const handleAdd = useEffectEvent(async ({ users, rid }: UsersInRolePayload) => { try { await Promise.all( users.map(async (user) => { if (user) { - await addUser({ roleName: _id, username: user, roomId: rid }); + await addUserToRoleEndpoint({ roleName: _id, username: user, roomId: rid }); } }), ); dispatchToastMessage({ type: 'success', message: t('Users_added') }); - reload.current(); - reset(); + queryClient.invalidateQueries(['getUsersInRole']); } catch (error) { dispatchToastMessage({ type: 'error', message: error }); } @@ -63,7 +57,7 @@ const UsersInRolePage = ({ role }: { role: IRole }): ReactElement => { - + @@ -71,40 +65,68 @@ const UsersInRolePage = ({ role }: { role: IRole }): ReactElement => { {role.scope !== 'Users' && ( - {t('Choose_a_room')} + {t('Choose_a_room')} ( - + rules={{ required: t('error-the-field-is-required', { field: t('Room') }) }} + render={({ field: { onChange, value } }) => ( + )} /> + {errors.rid && ( + + {errors.rid.message} + + )} )} - {t('Add_users')} + {t('Add_users')} ( - + rules={{ required: t('error-the-field-is-required', { field: t('Users') }) }} + render={({ field: { onChange, value } }) => ( + )} /> - + {errors.users && ( + + + {errors.users.message} + + + )} - {(role.scope === 'Users' || rid) && ( - - )} + {(role.scope === 'Users' || rid) && } {role.scope !== 'Users' && !rid && {t('Select_a_room')}} diff --git a/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/UsersInRoleTable.tsx b/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/UsersInRoleTable.tsx index ab8c5926f97f..ed7fdd93d79c 100644 --- a/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/UsersInRoleTable.tsx +++ b/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/UsersInRoleTable.tsx @@ -1,79 +1,107 @@ -import type { IRole, IRoom, IUserInRole } from '@rocket.chat/core-typings'; +import type { IRole, IRoom } from '@rocket.chat/core-typings'; import { Pagination } from '@rocket.chat/fuselage'; -import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { useEffectEvent } from '@rocket.chat/fuselage-hooks'; import { useSetModal, useToastMessageDispatch, useEndpoint, useTranslation } from '@rocket.chat/ui-contexts'; +import { useQuery, useQueryClient } from '@tanstack/react-query'; import type { ReactElement } from 'react'; -import React from 'react'; +import React, { useMemo } from 'react'; +import GenericError from '../../../../../components/GenericError'; import GenericModal from '../../../../../components/GenericModal'; import GenericNoResults from '../../../../../components/GenericNoResults'; -import { GenericTable, GenericTableHeader, GenericTableHeaderCell, GenericTableBody } from '../../../../../components/GenericTable'; -import type { usePagination } from '../../../../../components/GenericTable/hooks/usePagination'; +import { + GenericTable, + GenericTableHeader, + GenericTableHeaderCell, + GenericTableBody, + GenericTableLoadingTable, +} from '../../../../../components/GenericTable'; +import { usePagination } from '../../../../../components/GenericTable/hooks/usePagination'; import UsersInRoleTableRow from './UsersInRoleTableRow'; type UsersInRoleTableProps = { - users: IUserInRole[]; - reload: () => void; roleName: IRole['name']; roleId: IRole['_id']; description: IRole['description']; - total: number; rid?: IRoom['_id']; - paginationData: ReturnType; }; -// TODO: Missing error state -const UsersInRoleTable = ({ - users, - reload, - roleName, - roleId, - description, - total, - rid, - paginationData, -}: UsersInRoleTableProps): ReactElement => { +const UsersInRoleTable = ({ rid, roleId, roleName, description }: UsersInRoleTableProps): ReactElement => { const t = useTranslation(); const setModal = useSetModal(); const dispatchToastMessage = useToastMessageDispatch(); - const removeUser = useEndpoint('POST', '/v1/roles.removeUserFromRole'); - const { current, itemsPerPage, setItemsPerPage: onSetItemsPerPage, setCurrent: onSetCurrent, ...paginationProps } = paginationData; + const queryClient = useQueryClient(); - const closeModal = (): void => setModal(); + const getUsersInRoleEndpoint = useEndpoint('GET', '/v1/roles.getUsersInRole'); + const removeUserFromRoleEndpoint = useEndpoint('POST', '/v1/roles.removeUserFromRole'); - const handleRemove = useMutableCallback((username) => { - const remove = async (): Promise => { + const { current, itemsPerPage, setItemsPerPage: onSetItemsPerPage, setCurrent: onSetCurrent, ...paginationProps } = usePagination(); + + const query = useMemo( + () => ({ + role: roleId, + ...(rid && { roomId: rid }), + ...(itemsPerPage && { count: itemsPerPage }), + ...(current && { offset: current }), + }), + [itemsPerPage, current, rid, roleId], + ); + + const { data, isLoading, isSuccess, refetch, isError } = useQuery(['getUsersInRole', roleId, query], async () => + getUsersInRoleEndpoint(query), + ); + + const users = + data?.users?.map((user) => ({ + ...user, + createdAt: new Date(user.createdAt), + _updatedAt: new Date(user._updatedAt), + })) || []; + + const handleRemove = useEffectEvent((username) => { + const remove = async () => { try { - await removeUser({ roleId, username, scope: rid }); + await removeUserFromRoleEndpoint({ roleId, username, scope: rid }); dispatchToastMessage({ type: 'success', message: t('User_removed') }); - } catch (error: unknown) { + queryClient.invalidateQueries(['getUsersInRole']); + } catch (error) { dispatchToastMessage({ type: 'error', message: error }); } finally { - closeModal(); - reload(); + setModal(null); } }; setModal( - + setModal(null)} confirmText={t('Delete')}> {t('The_user_s_will_be_removed_from_role_s', username, description || roleName)} , ); }); + const headers = ( + <> + {t('Name')} + {t('Email')} + + + ); + return ( <> - {users.length === 0 && } - {users.length > 0 && ( + {isLoading && ( + + {headers} + + + + + )} + {isSuccess && users?.length > 0 && ( <> - - {t('Name')} - {t('Email')} - - + {headers} - {users.map((user) => ( + {users?.map((user) => ( ))} @@ -82,13 +110,15 @@ const UsersInRoleTable = ({ divider current={current} itemsPerPage={itemsPerPage} - count={total} + count={users.length || 0} onSetItemsPerPage={onSetItemsPerPage} onSetCurrent={onSetCurrent} {...paginationProps} /> )} + {users?.length === 0 && } + {isError && } ); }; diff --git a/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/UsersInRoleTableRow.tsx b/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/UsersInRoleTableRow.tsx index ea4b999d694e..4e860ca8f759 100644 --- a/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/UsersInRoleTableRow.tsx +++ b/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/UsersInRoleTableRow.tsx @@ -1,7 +1,8 @@ import type { IUserInRole } from '@rocket.chat/core-typings'; -import { Box, Button, Icon } from '@rocket.chat/fuselage'; -import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { Box, IconButton } from '@rocket.chat/fuselage'; +import { useEffectEvent } from '@rocket.chat/fuselage-hooks'; import { UserAvatar } from '@rocket.chat/ui-avatar'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import type { ReactElement } from 'react'; import React, { memo } from 'react'; @@ -14,10 +15,11 @@ type UsersInRoleTableRowProps = { }; const UsersInRoleTableRow = ({ user, onRemove }: UsersInRoleTableRowProps): ReactElement => { + const t = useTranslation(); const { _id, name, username, avatarETag } = user; const email = getUserEmailAddress(user); - const handleRemove = useMutableCallback(() => { + const handleRemove = useEffectEvent(() => { onRemove(username); }); @@ -27,26 +29,20 @@ const UsersInRoleTableRow = ({ user, onRemove }: UsersInRoleTableRowProps): Reac - - - {name || username} - - {name && ( - - {' '} - {`@${username}`}{' '} - - )} + + {name || username} + {name && ( + + {`@${username}`} + + )} {email} - - {/* FIXME: Replace to IconButton */} - + + ); diff --git a/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/UsersInRoleTableWithData.tsx b/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/UsersInRoleTableWithData.tsx deleted file mode 100644 index a7fe837b6e72..000000000000 --- a/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/UsersInRoleTableWithData.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import type { IRole, IRoom, IUserInRole } from '@rocket.chat/core-typings'; -import { useEndpoint, useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts'; -import { useQuery } from '@tanstack/react-query'; -import type { ReactElement, MutableRefObject } from 'react'; -import React, { useEffect, useMemo } from 'react'; - -import { usePagination } from '../../../../../components/GenericTable/hooks/usePagination'; -import UsersInRoleTable from './UsersInRoleTable'; - -type UsersInRoleTableWithDataProps = { - rid?: IRoom['_id']; - roleId: IRole['_id']; - roleName: IRole['name']; - description: IRole['description']; - reloadRef: MutableRefObject<() => void>; -}; - -const UsersInRoleTableWithData = ({ - rid, - roleId, - roleName, - description, - reloadRef, -}: UsersInRoleTableWithDataProps): ReactElement | null => { - const { itemsPerPage, current, ...paginationData } = usePagination(); - const t = useTranslation(); - - const query = useMemo( - () => ({ - role: roleId, - ...(rid && { roomId: rid }), - ...(itemsPerPage && { count: itemsPerPage }), - ...(current && { offset: current }), - }), - [itemsPerPage, current, rid, roleId], - ); - - const getUsersInRole = useEndpoint('GET', '/v1/roles.getUsersInRole'); - - const dispatchToastMessage = useToastMessageDispatch(); - - const { refetch, ...result } = useQuery( - ['roles', roleId, 'users', query], - async () => { - const { users } = await getUsersInRole(query); - - if (users.length === 0) { - throw new Error(t('No_results_found')); - } - return users; - }, - { - onError: (error) => { - dispatchToastMessage({ type: 'error', message: error }); - }, - }, - ); - - useEffect(() => { - reloadRef.current = refetch; - }, [refetch, reloadRef]); - - if (result.isLoading || result.error || !result.data) { - return null; - } - - const users: IUserInRole[] = result.data.map((user) => ({ - ...user, - createdAt: new Date(user.createdAt), - _updatedAt: new Date(user._updatedAt), - })); - - return ( - - ); -}; - -export default UsersInRoleTableWithData; diff --git a/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/index.ts b/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/index.ts index e7195afe4fd1..1557d53dff12 100644 --- a/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/index.ts +++ b/apps/meteor/client/views/admin/permissions/UsersInRole/UsersInRoleTable/index.ts @@ -1 +1 @@ -export { default } from './UsersInRoleTableWithData'; +export { default } from './UsersInRoleTable'; diff --git a/apps/meteor/client/views/admin/users/UsersTable/UsersTable.tsx b/apps/meteor/client/views/admin/users/UsersTable/UsersTable.tsx index 10ba211f27e0..93762f973c62 100644 --- a/apps/meteor/client/views/admin/users/UsersTable/UsersTable.tsx +++ b/apps/meteor/client/views/admin/users/UsersTable/UsersTable.tsx @@ -18,7 +18,7 @@ import { } from '../../../../components/GenericTable'; import type { usePagination } from '../../../../components/GenericTable/hooks/usePagination'; import type { useSort } from '../../../../components/GenericTable/hooks/useSort'; -import type { UsersFilters } from '../AdminUsersPage'; +import type { UsersFilters, UsersTableSortingOptions } from '../AdminUsersPage'; import UsersTableRow from './UsersTableRow'; type UsersTableProps = { @@ -27,7 +27,7 @@ type UsersTableProps = { setUserFilters: Dispatch>; filteredUsersQueryResult: UseQueryResult[] }>>; paginationData: ReturnType; - sortData: ReturnType>; + sortData: ReturnType>; }; // TODO: Missing error state @@ -104,19 +104,12 @@ const UsersTable = ({ ), mediaQuery && ( - + {t('Roles')} ), tab === 'all' && ( - + {t('Registration_status')} ), diff --git a/apps/meteor/client/views/room/contextualBar/Info/EditRoomInfo/EditRoomInfo.tsx b/apps/meteor/client/views/room/contextualBar/Info/EditRoomInfo/EditRoomInfo.tsx index 6b8d07779107..a32df8a44580 100644 --- a/apps/meteor/client/views/room/contextualBar/Info/EditRoomInfo/EditRoomInfo.tsx +++ b/apps/meteor/client/views/room/contextualBar/Info/EditRoomInfo/EditRoomInfo.tsx @@ -465,7 +465,7 @@ const EditRoomInfo = ({ room, onClickClose, onClickBack }: EditRoomInfoProps) => )} - {retentionPolicy?.enabled && ( + {canEditRoomRetentionPolicy && retentionPolicy?.enabled && ( @@ -486,12 +486,7 @@ const EditRoomInfo = ({ room, onClickClose, onClickBack }: EditRoomInfoProps) => control={control} name='retentionOverrideGlobal' render={({ field: { value, ...field } }) => ( - + )} /> diff --git a/apps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useMessageDeletionIsAllowed.ts b/apps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useMessageDeletionIsAllowed.ts index 31bc0ce7e2ca..fee190e36423 100644 --- a/apps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useMessageDeletionIsAllowed.ts +++ b/apps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useMessageDeletionIsAllowed.ts @@ -9,7 +9,7 @@ export const useMessageDeletionIsAllowed = (rid: IRoom['_id'], file: IUpload, ui const deletionIsEnabled = useSetting('Message_AllowDeleting'); const userHasPermissionToDeleteAny = usePermission('delete-message', rid); const userHasPermissionToDeleteOwn = usePermission('delete-own-message'); - const bypassBlockTimeLimit = usePermission('bypass-time-limit-edit-and-delete'); + const bypassBlockTimeLimit = usePermission('bypass-time-limit-edit-and-delete', rid); const blockDeleteInMinutes = useSetting('Message_AllowDeleting_BlockDeleteInMinutes'); const isDeletionAllowed = useMemo(() => { diff --git a/apps/meteor/client/views/root/MainLayout/LayoutWithSidebar.tsx b/apps/meteor/client/views/root/MainLayout/LayoutWithSidebar.tsx index b12a035d32cd..0fb26c0cbc22 100644 --- a/apps/meteor/client/views/root/MainLayout/LayoutWithSidebar.tsx +++ b/apps/meteor/client/views/root/MainLayout/LayoutWithSidebar.tsx @@ -1,15 +1,14 @@ -import { Box, PaletteStyleTag } from '@rocket.chat/fuselage'; +import { Box } from '@rocket.chat/fuselage'; import { useLayout, useSetting, useCurrentModal, useRoute, useCurrentRoutePath } from '@rocket.chat/ui-contexts'; -import { useThemeMode } from '@rocket.chat/ui-theming/src/hooks/useThemeMode'; import type { ReactElement, ReactNode } from 'react'; import React, { useEffect, useRef } from 'react'; import Sidebar from '../../../sidebar'; import AccessibilityShortcut from './AccessibilityShortcut'; +import { MainLayoutStyleTags } from './MainLayoutStyleTags'; const LayoutWithSidebar = ({ children }: { children: ReactNode }): ReactElement => { const { isEmbedded: embeddedLayout } = useLayout(); - const [, , theme] = useThemeMode(); const modal = useCurrentModal(); const currentRoutePath = useCurrentRoutePath(); @@ -48,8 +47,7 @@ const LayoutWithSidebar = ({ children }: { children: ReactNode }): ReactElement aria-hidden={Boolean(modal)} > - - + {!removeSidenav && }
{ + it('should create the Light theme style tag', () => { + render(, { + wrapper: mockAppRoot().withUserPreference('themeAppearence', 'light').build(), + }); + const tagLight = queryByAttribute('id', document.head, 'main-palette-light'); + expect(tagLight).not.toBeNull(); + }); + + it('should create the Dark theme style tag', () => { + render(, { + wrapper: mockAppRoot().withUserPreference('themeAppearence', 'dark').build(), + }); + const tagDark = queryByAttribute('id', document.head, 'main-palette-dark'); + expect(tagDark).not.toBeNull(); + }); + + it('should create the codeBlock style tag when in dark mode', () => { + render(, { + wrapper: mockAppRoot().withUserPreference('themeAppearence', 'dark').build(), + }); + const style = queryByAttribute('id', document.head, 'codeBlock-palette'); + expect(style).not.toBeNull(); + }); +}); diff --git a/apps/meteor/client/views/root/MainLayout/MainLayoutStyleTags.tsx b/apps/meteor/client/views/root/MainLayout/MainLayoutStyleTags.tsx new file mode 100644 index 000000000000..c830047a3424 --- /dev/null +++ b/apps/meteor/client/views/root/MainLayout/MainLayoutStyleTags.tsx @@ -0,0 +1,17 @@ +import { PaletteStyleTag } from '@rocket.chat/fuselage'; +import { useThemeMode } from '@rocket.chat/ui-theming/src/hooks/useThemeMode'; +import React from 'react'; + +import { codeBlock } from '../lib/codeBlockStyles'; + +export const MainLayoutStyleTags = () => { + const [, , theme] = useThemeMode(); + + return ( + <> + + + {theme === 'dark' && } + + ); +}; diff --git a/apps/meteor/client/views/root/lib/codeBlockStyles.ts b/apps/meteor/client/views/root/lib/codeBlockStyles.ts new file mode 100644 index 000000000000..2c6b4bf33be0 --- /dev/null +++ b/apps/meteor/client/views/root/lib/codeBlockStyles.ts @@ -0,0 +1,74 @@ +export const codeBlock = `pre code.hljs { + display: block; + overflow-x: auto; + padding: 1em; +} +code.hljs { + padding: 3px 5px; +} +.hljs { + background: #1d1f21; + color: #c5c8c6; +} +.hljs span::selection, +.hljs::selection { + background: #373b41; +} +.hljs span::-moz-selection, +.hljs::-moz-selection { + background: #373b41; +} +.hljs-name, +.hljs-title { + color: #f0c674; +} +.hljs-comment, +.hljs-meta, +.hljs-meta .hljs-keyword { + color: #707880; +} +.hljs-deletion, +.hljs-link, +.hljs-literal, +.hljs-number, +.hljs-symbol { + color: #c66; +} +.hljs-addition, +.hljs-doctag, +.hljs-regexp, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-string { + color: #b5bd68; +} +.hljs-attribute, +.hljs-code, +.hljs-selector-id { + color: #b294bb; +} +.hljs-bullet, +.hljs-keyword, +.hljs-selector-tag, +.hljs-tag { + color: #81a2be; +} +.hljs-subst, +.hljs-template-tag, +.hljs-template-variable, +.hljs-variable { + color: #8abeb7; +} +.hljs-built_in, +.hljs-quote, +.hljs-section, +.hljs-selector-class, +.hljs-type { + color: #de935f; +} +.hljs-emphasis { + font-style: italic; +} +.hljs-strong { + font-weight: 700; +}`; diff --git a/apps/meteor/client/views/teams/contextualBar/info/TeamsInfo.tsx b/apps/meteor/client/views/teams/contextualBar/info/TeamsInfo.tsx index 12e092b48763..5a38722cfc42 100644 --- a/apps/meteor/client/views/teams/contextualBar/info/TeamsInfo.tsx +++ b/apps/meteor/client/views/teams/contextualBar/info/TeamsInfo.tsx @@ -17,18 +17,10 @@ import RetentionPolicyCallout from '../../../../components/InfoPanel/RetentionPo import MarkdownText from '../../../../components/MarkdownText'; import type { Action } from '../../../hooks/useActionSpread'; import { useActionSpread } from '../../../hooks/useActionSpread'; - -type RetentionPolicy = { - retentionPolicyEnabled: boolean; - maxAgeDefault: number; - retentionEnabledDefault: boolean; - excludePinnedDefault: boolean; - filesOnlyDefault: boolean; -}; +import { useRetentionPolicy } from '../../../room/hooks/useRetentionPolicy'; type TeamsInfoProps = { room: IRoom; - retentionPolicy: RetentionPolicy; onClickHide: () => void; onClickClose: () => void; onClickLeave: () => void; @@ -40,7 +32,6 @@ type TeamsInfoProps = { const TeamsInfo = ({ room, - retentionPolicy, onClickHide, onClickClose, onClickLeave, @@ -51,7 +42,7 @@ const TeamsInfo = ({ }: TeamsInfoProps): ReactElement => { const t = useTranslation(); - const { retentionPolicyEnabled, filesOnlyDefault, excludePinnedDefault, maxAgeDefault } = retentionPolicy; + const retentionPolicy = useRetentionPolicy(room); const memoizedActions = useMemo( () => ({ @@ -199,8 +190,12 @@ const TeamsInfo = ({ )} - {retentionPolicyEnabled && ( - + {retentionPolicy?.isActive && ( + )} diff --git a/apps/meteor/client/views/teams/contextualBar/info/TeamsInfoWithData.js b/apps/meteor/client/views/teams/contextualBar/info/TeamsInfoWithData.js index f5cb4a44c5d2..0b2f84a339ed 100644 --- a/apps/meteor/client/views/teams/contextualBar/info/TeamsInfoWithData.js +++ b/apps/meteor/client/views/teams/contextualBar/info/TeamsInfoWithData.js @@ -3,7 +3,6 @@ import { useSetModal, useToastMessageDispatch, useUserId, - useSetting, usePermission, useMethod, useTranslation, @@ -23,33 +22,12 @@ import ConvertToChannelModal from '../../ConvertToChannelModal'; import LeaveTeam from './LeaveTeam'; import TeamsInfo from './TeamsInfo'; -const retentionPolicyMaxAge = { - c: 'RetentionPolicy_MaxAge_Channels', - p: 'RetentionPolicy_MaxAge_Groups', - d: 'RetentionPolicy_MaxAge_DMs', -}; - -const retentionPolicyAppliesTo = { - c: 'RetentionPolicy_AppliesToChannels', - p: 'RetentionPolicy_AppliesToGroups', - d: 'RetentionPolicy_AppliesToDMs', -}; - const TeamsInfoWithLogic = ({ openEditing }) => { const room = useRoom(); const { openTab, closeTab } = useRoomToolbox(); const t = useTranslation(); const userId = useUserId(); - const retentionPolicyEnabled = useSetting('RetentionPolicy_Enabled'); - const retentionPolicy = { - retentionPolicyEnabled, - maxAgeDefault: useSetting(retentionPolicyMaxAge[room.t]) || 30, - retentionEnabledDefault: useSetting(retentionPolicyAppliesTo[room.t]), - excludePinnedDefault: useSetting('RetentionPolicy_DoNotPrunePinned'), - filesOnlyDefault: useSetting('RetentionPolicy_FilesOnly'), - }; - const dontAskHideRoom = useDontAskAgain('hideRoom'); const dispatchToastMessage = useToastMessageDispatch(); @@ -153,7 +131,6 @@ const TeamsInfoWithLogic = ({ openEditing }) => { return ( Updated dependencies [ff4e396416, ad86761209, f83bd56cc5, 724ba3a729, ee5cdfc367, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/core-services@0.3.15 + - @rocket.chat/rest-typings@6.9.0 + - @rocket.chat/ui-kit@0.34.0 + - @rocket.chat/model-typings@0.4.1 + - @rocket.chat/models@0.0.39 + + +## 1.1.33-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/rest-typings@6.9.0-rc.2 + - @rocket.chat/core-services@0.3.15-rc.2 + - @rocket.chat/model-typings@0.4.1-rc.2 + - @rocket.chat/models@0.0.39-rc.2 +
+ +## 1.1.33-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/rest-typings@6.9.0-rc.1 + - @rocket.chat/core-services@0.3.15-rc.1 + - @rocket.chat/model-typings@0.4.1-rc.1 + - @rocket.chat/models@0.0.39-rc.1 +
+ +## 1.1.33-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, f83bd56cc5, 724ba3a729, ee5cdfc367, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/core-services@0.3.15-rc.0 + - @rocket.chat/rest-typings@6.9.0-rc.0 + - @rocket.chat/ui-kit@0.34.0-rc.0 + - @rocket.chat/model-typings@0.4.1-rc.0 + - @rocket.chat/models@0.0.39-rc.0 +
+ ## 1.1.32 ### Patch Changes diff --git a/apps/meteor/ee/server/services/package.json b/apps/meteor/ee/server/services/package.json index 3a22d3965385..c2119b1d3b24 100644 --- a/apps/meteor/ee/server/services/package.json +++ b/apps/meteor/ee/server/services/package.json @@ -1,7 +1,7 @@ { "name": "rocketchat-services", "private": true, - "version": "1.1.32", + "version": "1.1.33", "description": "Rocket.Chat Authorization service", "main": "index.js", "scripts": { @@ -50,7 +50,7 @@ "ws": "^8.8.1" }, "devDependencies": { - "@rocket.chat/icons": "^0.35.0", + "@rocket.chat/icons": "^0.36.0", "@types/cookie": "^0.5.3", "@types/cookie-parser": "^1.4.5", "@types/ejson": "^2.2.1", diff --git a/apps/meteor/ee/server/startup/presence.ts b/apps/meteor/ee/server/startup/presence.ts index 3e8daad4b259..0e7ba8a2b951 100644 --- a/apps/meteor/ee/server/startup/presence.ts +++ b/apps/meteor/ee/server/startup/presence.ts @@ -30,7 +30,7 @@ Meteor.startup(() => { }); Accounts.onLogin((login: any): void => { - if (login.type !== 'resume' || !login.connection.id) { + if (!login.connection.id) { return; } diff --git a/apps/meteor/package.json b/apps/meteor/package.json index 127439f74c09..d79155167845 100644 --- a/apps/meteor/package.json +++ b/apps/meteor/package.json @@ -1,7 +1,7 @@ { "name": "@rocket.chat/meteor", "description": "The Ultimate Open Source WebChat Platform", - "version": "6.9.0-develop", + "version": "6.10.0-develop", "private": true, "author": { "name": "Rocket.Chat", @@ -242,7 +242,7 @@ "@rocket.chat/favicon": "workspace:^", "@rocket.chat/forked-matrix-appservice-bridge": "^4.0.2", "@rocket.chat/forked-matrix-bot-sdk": "^0.6.0-beta.3", - "@rocket.chat/fuselage": "^0.53.7", + "@rocket.chat/fuselage": "^0.54.2", "@rocket.chat/fuselage-hooks": "^0.33.1", "@rocket.chat/fuselage-polyfills": "~0.31.25", "@rocket.chat/fuselage-toastbar": "^0.31.26", @@ -250,7 +250,7 @@ "@rocket.chat/fuselage-ui-kit": "workspace:^", "@rocket.chat/gazzodown": "workspace:^", "@rocket.chat/i18n": "workspace:^", - "@rocket.chat/icons": "^0.35.0", + "@rocket.chat/icons": "^0.36.0", "@rocket.chat/instance-status": "workspace:^", "@rocket.chat/jwt": "workspace:^", "@rocket.chat/layout": "~0.31.26", diff --git a/apps/meteor/server/database/watchCollections.ts b/apps/meteor/server/database/watchCollections.ts index 244159cb3e20..d8862ab47a53 100644 --- a/apps/meteor/server/database/watchCollections.ts +++ b/apps/meteor/server/database/watchCollections.ts @@ -32,10 +32,7 @@ export function getWatchCollections(): string[] { const collections = [ Users.getCollectionName(), LivechatInquiry.getCollectionName(), - LivechatDepartmentAgents.getCollectionName(), InstanceStatus.getCollectionName(), - IntegrationHistory.getCollectionName(), - EmailInbox.getCollectionName(), Settings.getCollectionName(), Subscriptions.getCollectionName(), ]; @@ -50,6 +47,9 @@ export function getWatchCollections(): string[] { collections.push(Permissions.getCollectionName()); collections.push(LivechatPriority.getCollectionName()); collections.push(LoginServiceConfiguration.getCollectionName()); + collections.push(EmailInbox.getCollectionName()); + collections.push(IntegrationHistory.getCollectionName()); + collections.push(LivechatDepartmentAgents.getCollectionName()); } if (onlyCollections.length > 0) { diff --git a/apps/meteor/server/email/IMAPInterceptor.ts b/apps/meteor/server/email/IMAPInterceptor.ts index 3371087d551c..c599608cb182 100644 --- a/apps/meteor/server/email/IMAPInterceptor.ts +++ b/apps/meteor/server/email/IMAPInterceptor.ts @@ -6,6 +6,7 @@ import IMAP from 'imap'; import type { ParsedMail } from 'mailparser'; import { simpleParser } from 'mailparser'; +import { notifyOnEmailInboxChanged } from '../../app/lib/server/lib/notifyListener'; import { logger } from '../features/EmailInbox/logger'; type IMAPOptions = { @@ -221,9 +222,15 @@ export class IMAPInterceptor extends EventEmitter { async selfDisable(): Promise { logger.info(`Disabling inbox ${this.inboxId}`); + // Again, if there's 2 inboxes with the same email, this will prevent looping over the already disabled one // Active filter is just in case :) - await EmailInbox.findOneAndUpdate({ _id: this.inboxId, active: true }, { $set: { active: false } }); + const { value } = await EmailInbox.setDisabledById(this.inboxId); + + if (value) { + void notifyOnEmailInboxChanged(value, 'updated'); + } + logger.info(`IMAP inbox ${this.inboxId} automatically disabled`); } } diff --git a/apps/meteor/server/features/EmailInbox/EmailInbox.ts b/apps/meteor/server/features/EmailInbox/EmailInbox.ts index 18b273c43012..f9c4422f88e0 100644 --- a/apps/meteor/server/features/EmailInbox/EmailInbox.ts +++ b/apps/meteor/server/features/EmailInbox/EmailInbox.ts @@ -18,9 +18,7 @@ export type Inbox = { export const inboxes = new Map(); export async function configureEmailInboxes(): Promise { - const emailInboxesCursor = EmailInbox.find({ - active: true, - }); + const emailInboxesCursor = EmailInbox.findActive(); logger.info('Clearing old email inbox registrations'); for (const { imap } of inboxes.values()) { diff --git a/apps/meteor/server/models/dummy/BaseDummy.ts b/apps/meteor/server/models/dummy/BaseDummy.ts index c417213f5a36..9c91036d3969 100644 --- a/apps/meteor/server/models/dummy/BaseDummy.ts +++ b/apps/meteor/server/models/dummy/BaseDummy.ts @@ -131,6 +131,13 @@ export class BaseDummy< }; } + async removeByIds(_ids: T['_id'][]): Promise { + return { + acknowledged: true, + deletedCount: 0, + }; + } + async deleteOne(filter: Filter, options?: DeleteOptions & { bypassDocumentValidation?: boolean }): Promise { return this.deleteMany(filter, options); } diff --git a/apps/meteor/server/models/raw/BaseRaw.ts b/apps/meteor/server/models/raw/BaseRaw.ts index 5ab3b9802105..96f64b061ade 100644 --- a/apps/meteor/server/models/raw/BaseRaw.ts +++ b/apps/meteor/server/models/raw/BaseRaw.ts @@ -267,6 +267,10 @@ export abstract class BaseRaw< return this.deleteOne({ _id } as Filter); } + removeByIds(ids: T['_id'][]): Promise { + return this.deleteMany({ _id: { $in: ids } } as unknown as Filter); + } + async deleteOne(filter: Filter, options?: DeleteOptions & { bypassDocumentValidation?: boolean }): Promise { if (!this.trash) { if (options) { diff --git a/apps/meteor/server/models/raw/EmailInbox.ts b/apps/meteor/server/models/raw/EmailInbox.ts index 138b7bc0296d..edb17c8f8616 100644 --- a/apps/meteor/server/models/raw/EmailInbox.ts +++ b/apps/meteor/server/models/raw/EmailInbox.ts @@ -1,6 +1,6 @@ import type { IEmailInbox, RocketChatRecordDeleted } from '@rocket.chat/core-typings'; import type { IEmailInboxModel } from '@rocket.chat/model-typings'; -import type { Collection, Db, IndexDescription } from 'mongodb'; +import type { Collection, Db, FindCursor, IndexDescription, InsertOneResult, ModifyResult, UpdateFilter } from 'mongodb'; import { BaseRaw } from './BaseRaw'; @@ -12,4 +12,27 @@ export class EmailInboxRaw extends BaseRaw implements IEmailInboxMo protected modelIndexes(): IndexDescription[] { return [{ key: { email: 1 }, unique: true }]; } + + async setDisabledById(id: IEmailInbox['_id']): Promise> { + return this.findOneAndUpdate({ _id: id, active: true }, { $set: { active: false } }, { returnDocument: 'after' }); + } + + async create(emailInbox: IEmailInbox): Promise> { + return this.insertOne(emailInbox); + } + + async updateById(id: IEmailInbox['_id'], data: UpdateFilter): Promise>> { + // findOneAndUpdate doesn't accept generics, so we had to type cast + return this.findOneAndUpdate({ _id: id }, data, { returnDocument: 'after', projection: { _id: 1 } }) as unknown as Promise< + ModifyResult> + >; + } + + findActive(): FindCursor { + return this.find({ active: true }); + } + + async findByEmail(email: IEmailInbox['email']): Promise { + return this.findOne({ email }); + } } diff --git a/apps/meteor/server/models/raw/IntegrationHistory.ts b/apps/meteor/server/models/raw/IntegrationHistory.ts index 611c7ca095f1..317bdf41caf0 100644 --- a/apps/meteor/server/models/raw/IntegrationHistory.ts +++ b/apps/meteor/server/models/raw/IntegrationHistory.ts @@ -1,6 +1,6 @@ import type { IIntegrationHistory } from '@rocket.chat/core-typings'; import type { IIntegrationHistoryModel } from '@rocket.chat/model-typings'; -import type { Db, IndexDescription } from 'mongodb'; +import type { Db, IndexDescription, InsertOneResult, FindOneAndUpdateOptions } from 'mongodb'; import { BaseRaw } from './BaseRaw'; @@ -23,4 +23,17 @@ export class IntegrationHistoryRaw extends BaseRaw implemen findOneByIntegrationIdAndHistoryId(integrationId: string, historyId: string): Promise { return this.findOne({ 'integration._id': integrationId, '_id': historyId }); } + + async create(integrationHistory: IIntegrationHistory): Promise> { + return this.insertOne({ ...integrationHistory, _createdAt: new Date() }); + } + + async updateById( + _id: IIntegrationHistory['_id'], + data: Partial, + options?: FindOneAndUpdateOptions, + ): Promise { + const response = await this.findOneAndUpdate({ _id }, { $set: data }, { returnDocument: 'after', ...options }); + return response.value; + } } diff --git a/apps/meteor/server/models/raw/LivechatDepartment.ts b/apps/meteor/server/models/raw/LivechatDepartment.ts index a54b03876dd9..b8263af030a8 100644 --- a/apps/meteor/server/models/raw/LivechatDepartment.ts +++ b/apps/meteor/server/models/raw/LivechatDepartment.ts @@ -16,6 +16,7 @@ import type { AggregationCursor, } from 'mongodb'; +import { notifyOnLivechatDepartmentAgentChangedByDepartmentId } from '../../../app/lib/server/lib/notifyListener'; import { BaseRaw } from './BaseRaw'; export class LivechatDepartmentRaw extends BaseRaw implements ILivechatDepartmentModel { @@ -251,6 +252,7 @@ export class LivechatDepartmentRaw extends BaseRaw implemen if (current?.enabled !== data.enabled) { await LivechatDepartmentAgents.setDepartmentEnabledByDepartmentId(_id, data.enabled); + void notifyOnLivechatDepartmentAgentChangedByDepartmentId(_id, current ? 'updated' : 'inserted'); } const latestDept = await this.findOneById(_id); diff --git a/apps/meteor/server/models/raw/LivechatDepartmentAgents.ts b/apps/meteor/server/models/raw/LivechatDepartmentAgents.ts index 082a3e6aa2e6..76a0e7610445 100644 --- a/apps/meteor/server/models/raw/LivechatDepartmentAgents.ts +++ b/apps/meteor/server/models/raw/LivechatDepartmentAgents.ts @@ -152,7 +152,7 @@ export class LivechatDepartmentAgentsRaw extends BaseRaw { - return this.deleteOne({ departmentId }); + return this.deleteMany({ departmentId }); } findByDepartmentId(departmentId: string, options?: FindOptions): FindCursor { @@ -174,7 +174,7 @@ export class LivechatDepartmentAgentsRaw extends BaseRaw { + }): Promise { return this.updateOne( { agentId: agent.agentId, @@ -192,8 +192,8 @@ export class LivechatDepartmentAgentsRaw extends BaseRaw { - await this.deleteMany({ agentId }); + async removeByAgentId(agentId: string): Promise { + return this.deleteMany({ agentId }); } async removeByDepartmentIdAndAgentId(departmentId: string, agentId: string): Promise { @@ -201,11 +201,11 @@ export class LivechatDepartmentAgentsRaw extends BaseRaw, - ): Promise<{ agentId: string; username: string } | null | undefined> { + ): Promise | null | undefined> { const agents = await this.findByDepartmentId(departmentId).toArray(); if (agents.length === 0) { @@ -231,25 +231,28 @@ export class LivechatDepartmentAgentsRaw extends BaseRaw { @@ -311,15 +314,19 @@ export class LivechatDepartmentAgentsRaw extends BaseRaw { + async getNextBotForDepartment( + departmentId: ILivechatDepartmentAgents['departmentId'], + ignoreAgentId?: ILivechatDepartmentAgents['agentId'], + ): Promise | null | undefined> { const agents = await this.findByDepartmentId(departmentId).toArray(); - if (agents.length === 0) { + if (!agents.length) { return; } - const botUsers = await Users.findBotAgents(agents.map((a) => a.username)).toArray(); - const botUsernames = botUsers.map((user) => user.username).filter(isStringValue); + const botUsernames = (await Users.findBotAgents(agents.map((a) => a.username)).toArray()) + .map((user) => user.username) + .filter(isStringValue); const query = { departmentId, @@ -329,24 +336,28 @@ export class LivechatDepartmentAgentsRaw extends BaseRaw { @@ -376,6 +387,14 @@ export class LivechatDepartmentAgentsRaw extends BaseRaw { return this.col.distinct('agentId', { departmentId: { $in: departmentIds }, departmentEnabled: true }); } + + findByAgentsAndDepartmentId( + agentsIds: ILivechatDepartmentAgents['agentId'][], + departmentId: ILivechatDepartmentAgents['departmentId'], + options?: FindOptions, + ): FindCursor { + return this.find({ agentId: { $in: agentsIds }, departmentId }, options); + } } const isStringValue = (value: any): value is string => typeof value === 'string'; diff --git a/apps/meteor/tests/data/users.helper.js b/apps/meteor/tests/data/users.helper.js index cf6f90b3f877..841ec56d7db1 100644 --- a/apps/meteor/tests/data/users.helper.js +++ b/apps/meteor/tests/data/users.helper.js @@ -1,6 +1,8 @@ import { UserStatus } from '@rocket.chat/core-typings'; import { api, credentials, request } from './api-data'; import { password } from './user'; +import { MongoClient } from 'mongodb'; +import { URL_MONGODB } from '../e2e/config/constants'; export const createUser = (userData = {}) => new Promise((resolve) => { @@ -105,3 +107,15 @@ export const registerUser = async (userData = {}, overrideCredentials = credenti return result.body.user; }; + +// For changing user data when it's not possible to do so via API +export const updateUserInDb = async (userId, userData) => { + const connection = await MongoClient.connect(URL_MONGODB); + + await connection + .db() + .collection('users') + .updateOne({ _id: userId }, { $set: { ...userData } }); + + await connection.close(); +}; diff --git a/apps/meteor/tests/e2e/.eslintrc.json b/apps/meteor/tests/e2e/.eslintrc.json index 303264be56f0..aa970258b4c7 100644 --- a/apps/meteor/tests/e2e/.eslintrc.json +++ b/apps/meteor/tests/e2e/.eslintrc.json @@ -1,6 +1,6 @@ { "root": true, - "extends": ["@rocket.chat/eslint-config/original", "@rocket.chat/eslint-config/react", "prettier", "plugin:@typescript-eslint/recommended"], + "extends": ["@rocket.chat/eslint-config", "@rocket.chat/eslint-config/react", "prettier", "plugin:@typescript-eslint/recommended"], "parser": "@typescript-eslint/parser", "plugins": ["prettier", "testing-library", "anti-trojan-source", "no-floating-promise"], "rules": { diff --git a/apps/meteor/tests/e2e/access-security-page.spec.ts b/apps/meteor/tests/e2e/access-security-page.spec.ts index 40153892dd32..590f41297ef2 100644 --- a/apps/meteor/tests/e2e/access-security-page.spec.ts +++ b/apps/meteor/tests/e2e/access-security-page.spec.ts @@ -27,7 +27,7 @@ test.describe.serial('access-security-page', () => { setSettingValueById(api, 'Accounts_AllowPasswordChange', true), setSettingValueById(api, 'Accounts_TwoFactorAuthentication_Enabled', true), setSettingValueById(api, 'E2E_Enable', false), - ]) + ]), ); test('security tab is invisible when password change, 2FA and E2E are disabled', async ({ page }) => { @@ -77,5 +77,5 @@ test.describe.serial('access-security-page', () => { ]); await expect(poAccountProfile.securityE2EEncryptionSection).toBeVisible(); }); - }) + }); }); diff --git a/apps/meteor/tests/e2e/account-profile.spec.ts b/apps/meteor/tests/e2e/account-profile.spec.ts index e287a1c694c4..c549a8b420c7 100644 --- a/apps/meteor/tests/e2e/account-profile.spec.ts +++ b/apps/meteor/tests/e2e/account-profile.spec.ts @@ -21,51 +21,51 @@ test.describe.serial('settings-account-profile', () => { test.describe('Profile', () => { test.beforeEach(async ({ page }) => { await page.goto('/account/profile'); - }) + }); test.skip('expect update profile with new name/username', async () => { const newName = faker.person.fullName(); const newUsername = faker.internet.userName({ firstName: newName }); - + await poAccountProfile.inputName.fill(newName); await poAccountProfile.inputUsername.fill(newUsername); await poAccountProfile.btnSubmit.click(); await poAccountProfile.btnClose.click(); await poHomeChannel.sidenav.openChat('general'); await poHomeChannel.content.sendMessage('any_message'); - + await expect(poHomeChannel.content.lastUserMessageNotSequential).toContainText(newUsername); - + await poHomeChannel.content.lastUserMessageNotSequential.locator('figure').click(); await poHomeChannel.content.linkUserCard.click(); - + await expect(poHomeChannel.tabs.userInfoUsername).toHaveText(newUsername); - }) + }); test.describe('Avatar', () => { - test('should change avatar image by uploading file', async () => { + test('should change avatar image by uploading file', async () => { await poAccountProfile.inputImageFile.setInputFiles('./tests/e2e/fixtures/files/test-image.jpeg'); await poAccountProfile.btnSubmit.click(); - + await expect(poAccountProfile.userAvatarEditor).toHaveAttribute('src'); }); - test('should change avatar image from url', async () => { + test('should change avatar image from url', async () => { await poAccountProfile.inputAvatarLink.fill('https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50'); await poAccountProfile.btnSetAvatarLink.click(); - + await poAccountProfile.btnSubmit.click(); await expect(poAccountProfile.userAvatarEditor).toHaveAttribute('src'); }); - test('should display a skeleton if the image url is not valid', async () => { + test('should display a skeleton if the image url is not valid', async () => { await poAccountProfile.inputAvatarLink.fill('https://invalidUrl'); await poAccountProfile.btnSetAvatarLink.click(); - + await poAccountProfile.btnSubmit.click(); await expect(poAccountProfile.userAvatarEditor).not.toHaveAttribute('src'); }); - }) + }); }); test.describe('Security', () => { @@ -74,8 +74,8 @@ test.describe.serial('settings-account-profile', () => { const results = await makeAxeBuilder().analyze(); expect(results.violations).toEqual([]); - }) - }) + }); + }); test('Personal Access Tokens', async ({ page }) => { const response = page.waitForResponse('**/api/v1/users.getPersonalAccessTokens'); @@ -120,8 +120,8 @@ test.describe.serial('settings-account-profile', () => { const results = await makeAxeBuilder().analyze(); expect(results.violations).toEqual([]); - }) - }) + }); + }); test.describe('Feature Preview', () => { test('should not have any accessibility violations', async ({ page, makeAxeBuilder }) => { @@ -129,8 +129,8 @@ test.describe.serial('settings-account-profile', () => { const results = await makeAxeBuilder().analyze(); expect(results.violations).toEqual([]); - }) - }) + }); + }); test.describe('Accessibility & Appearance', () => { test('should not have any accessibility violations', async ({ page, makeAxeBuilder }) => { @@ -138,8 +138,6 @@ test.describe.serial('settings-account-profile', () => { const results = await makeAxeBuilder().analyze(); expect(results.violations).toEqual([]); - }) - }) + }); + }); }); - - diff --git a/apps/meteor/tests/e2e/administration.spec.ts b/apps/meteor/tests/e2e/administration.spec.ts index c778e165a769..902d4f09b12c 100644 --- a/apps/meteor/tests/e2e/administration.spec.ts +++ b/apps/meteor/tests/e2e/administration.spec.ts @@ -2,7 +2,7 @@ import { faker } from '@faker-js/faker'; import { IS_EE } from './config/constants'; import { Users } from './fixtures/userStates'; -import { Admin } from './page-objects'; +import { Admin, Utils } from './page-objects'; import { createTargetChannel } from './utils'; import { setSettingValueById } from './utils/setSettingValueById'; import { test, expect } from './utils/test'; @@ -11,10 +11,12 @@ test.use({ storageState: Users.admin.state }); test.describe.parallel('administration', () => { let poAdmin: Admin; + let poUtils: Utils; let targetChannel: string; test.beforeEach(async ({ page }) => { poAdmin = new Admin(page); + poUtils = new Utils(page); }); test.describe('Workspace', () => { @@ -202,29 +204,64 @@ test.describe.parallel('administration', () => { test('expect open upsell modal if not enterprise', async ({ page }) => { test.skip(IS_EE); await poAdmin.btnCreateRole.click(); - await page.waitForSelector('role=dialog[name="Custom roles"]'); + await expect(page.getByRole('dialog', { name: 'Custom roles' })).toBeVisible(); }); test.describe('Users in role', () => { const channelName = faker.string.uuid(); test.beforeAll(async ({ api }) => { - // TODO: refactor createChannel utility in order to get channel data when creating + // TODO: refactor createChannel utility in order to get channel data when creating const response = await api.post('/channels.create', { name: channelName, members: ['user1'] }); const { channel } = await response.json(); await api.post('/channels.addOwner', { roomId: channel._id, userId: Users.user1.data._id }); await api.post('/channels.removeOwner', { roomId: channel._id, userId: Users.admin.data._id }); - }) + }); test('admin should be able to get the owners of a room that wasnt created by him', async ({ page }) => { await poAdmin.openRoleByName('Owner').click(); await poAdmin.btnUsersInRole.click(); await poAdmin.inputRoom.fill(channelName); await page.getByRole('option', { name: channelName }).click(); - + await expect(poAdmin.getUserRowByUsername('user1')).toBeVisible(); - }) - }) + }); + + test('should add user1 as moderator of target channel', async ({ page }) => { + await poAdmin.openRoleByName('Moderator').click(); + await poAdmin.btnUsersInRole.click(); + + await poAdmin.inputRoom.fill(channelName); + await page.getByRole('option', { name: channelName }).click(); + + await poAdmin.inputUsers.fill('user1'); + await page.getByRole('option', { name: 'user1' }).click(); + await poAdmin.btnAdd.click(); + + await expect(poAdmin.getUserRowByUsername('user1')).toBeVisible(); + }); + + test('should remove user1 as moderator of target channel', async ({ page }) => { + await poAdmin.openRoleByName('Moderator').click(); + await poAdmin.btnUsersInRole.click(); + + await poAdmin.inputRoom.fill(channelName); + await page.getByRole('option', { name: channelName }).click(); + + await poAdmin.getUserRowByUsername('user1').getByRole('button', { name: 'Remove' }).click(); + await poUtils.btnModalConfirmDelete.click(); + + await expect(page.locator('h3 >> text="No results found"')).toBeVisible(); + }); + + test('should back to the permissions page', async ({ page }) => { + await poAdmin.openRoleByName('Moderator').click(); + await poAdmin.btnUsersInRole.click(); + await poAdmin.btnBack.click(); + + await expect(page.locator('h1 >> text="Permissions"')).toBeVisible(); + }); + }); }); test.describe('Mailer', () => { @@ -245,7 +282,7 @@ test.describe.parallel('administration', () => { }); test.afterAll(async ({ api }) => { - await setSettingValueById(api, 'Language', 'en') + await setSettingValueById(api, 'Language', 'en'); }); test('expect be able to reset a setting after a change', async () => { diff --git a/apps/meteor/tests/e2e/channel-management.spec.ts b/apps/meteor/tests/e2e/channel-management.spec.ts index aeaa74773354..f9c779b728b9 100644 --- a/apps/meteor/tests/e2e/channel-management.spec.ts +++ b/apps/meteor/tests/e2e/channel-management.spec.ts @@ -146,7 +146,7 @@ test.describe.serial('channel-management', () => { await user1Page.close(); }); - + test('should set user1 as moderator', async ({ browser }) => { await poHomeChannel.sidenav.openChat(targetChannel); await poHomeChannel.tabs.btnTabMembers.click(); @@ -264,7 +264,7 @@ test.describe.serial('channel-management', () => { await page.getByRole('button', { name: targetChannel }).first().focus(); await page.keyboard.press('Space'); await page.getByRole('dialog').waitFor(); - + await expect(page.getByRole('dialog')).toBeVisible(); }); @@ -275,7 +275,7 @@ test.describe.serial('channel-management', () => { await page.getByRole('menuitem', { name: 'Discussion' }).click(); await page.getByRole('textbox', { name: 'Name' }).fill(discussionName); await page.getByRole('button', { name: 'Create' }).click(); - + await expect(page.getByRole('heading', { name: discussionName })).toBeVisible(); }); @@ -286,7 +286,7 @@ test.describe.serial('channel-management', () => { await page.keyboard.press('Tab'); await page.keyboard.press('Tab'); await page.keyboard.press('Space'); - + await expect(page).toHaveURL(`/channel/${targetChannel}`); }); diff --git a/apps/meteor/tests/e2e/e2e-encryption.spec.ts b/apps/meteor/tests/e2e/e2e-encryption.spec.ts index 55de92ef8bad..b33365c5dce0 100644 --- a/apps/meteor/tests/e2e/e2e-encryption.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption.spec.ts @@ -447,5 +447,4 @@ test.describe.serial('e2ee room setup', () => { await expect(poHomeChannel.content.inputMessage).not.toBeVisible(); await expect(page.locator('.rcx-states__title')).toContainText('Check back later'); }); - }); diff --git a/apps/meteor/tests/e2e/federation/page-objects/fragments/home-content.ts b/apps/meteor/tests/e2e/federation/page-objects/fragments/home-content.ts index 2534bf817a30..532cca6795fc 100644 --- a/apps/meteor/tests/e2e/federation/page-objects/fragments/home-content.ts +++ b/apps/meteor/tests/e2e/federation/page-objects/fragments/home-content.ts @@ -264,12 +264,14 @@ export class FederationHomeContent { async openLastThreadMessageMenu(): Promise { await this.page.getByRole('dialog').locator('[data-qa-type="message"]').last().hover(); await this.page - .getByRole('dialog').locator('[data-qa-type="message"]') + .getByRole('dialog') + .locator('[data-qa-type="message"]') .last() .locator('[data-qa-type="message-action-menu"][data-qa-id="menu"]') .waitFor(); await this.page - .getByRole('dialog').locator('[data-qa-type="message"]') + .getByRole('dialog') + .locator('[data-qa-type="message"]') .last() .locator('[data-qa-type="message-action-menu"][data-qa-id="menu"]') .click(); diff --git a/apps/meteor/tests/e2e/federation/tests/messaging/threads.spec.ts b/apps/meteor/tests/e2e/federation/tests/messaging/threads.spec.ts index d52af145dae2..f03e33ebdc3d 100644 --- a/apps/meteor/tests/e2e/federation/tests/messaging/threads.spec.ts +++ b/apps/meteor/tests/e2e/federation/tests/messaging/threads.spec.ts @@ -90,22 +90,22 @@ test.describe.only('Federation - Threads', () => { await poFederationChannelServer1.content.sendMessage('hello world from server A'); await poFederationChannelServer2.content.openLastMessageMenu(); - await poFederationChannelServer2.content.btnOptionReplyInThread.click(); + await poFederationChannelServer2.content.btnOptionReplyInThread.click(); - await expect(pageForServer2).toHaveURL(/.*thread/); + await expect(pageForServer2).toHaveURL(/.*thread/); - await expect(poFederationChannelServer2.content.threadSendToChannelAlso()).not.toBeVisible(); + await expect(poFederationChannelServer2.content.threadSendToChannelAlso()).not.toBeVisible(); - await poFederationChannelServer2.content.sendThreadMessage('This is a thread message sent from server B'); + await poFederationChannelServer2.content.sendThreadMessage('This is a thread message sent from server B'); - await expect(poFederationChannelServer2.content.lastThreadMessageText).toContainText('This is a thread message sent from server B'); - await expect(poFederationChannelServer2.content.lastUserMessage).toContainText('This is a thread message sent from server B'); + await expect(poFederationChannelServer2.content.lastThreadMessageText).toContainText('This is a thread message sent from server B'); + await expect(poFederationChannelServer2.content.lastUserMessage).toContainText('This is a thread message sent from server B'); - await poFederationChannelServer1.content.openLastMessageMenu(); - await poFederationChannelServer1.content.btnOptionReplyInThread.click(); + await poFederationChannelServer1.content.openLastMessageMenu(); + await poFederationChannelServer1.content.btnOptionReplyInThread.click(); - await expect(page).toHaveURL(/.*thread/); - await expect(poFederationChannelServer1.content.lastThreadMessageText).toContainText('This is a thread message sent from server B'); + await expect(page).toHaveURL(/.*thread/); + await expect(poFederationChannelServer1.content.lastThreadMessageText).toContainText('This is a thread message sent from server B'); }); test('expect to send a thread message from Server A to Server B', async ({ page }) => { @@ -117,24 +117,24 @@ test.describe.only('Federation - Threads', () => { await poFederationChannelServer2.content.sendMessage('hello world from server B'); await poFederationChannelServer1.content.openLastMessageMenu(); - await poFederationChannelServer1.content.btnOptionReplyInThread.click(); + await poFederationChannelServer1.content.btnOptionReplyInThread.click(); - await expect(page).toHaveURL(/.*thread/); + await expect(page).toHaveURL(/.*thread/); - await expect(poFederationChannelServer1.content.threadSendToChannelAlso()).not.toBeVisible(); + await expect(poFederationChannelServer1.content.threadSendToChannelAlso()).not.toBeVisible(); - await poFederationChannelServer1.content.sendThreadMessage('This is a thread message sent from server A'); + await poFederationChannelServer1.content.sendThreadMessage('This is a thread message sent from server A'); - await expect(poFederationChannelServer1.content.lastThreadMessageText).toContainText('This is a thread message sent from server A'); - await expect(poFederationChannelServer1.content.lastUserMessage).toContainText('This is a thread message sent from server A'); + await expect(poFederationChannelServer1.content.lastThreadMessageText).toContainText('This is a thread message sent from server A'); + await expect(poFederationChannelServer1.content.lastUserMessage).toContainText('This is a thread message sent from server A'); - await poFederationChannelServer2.content.openLastMessageMenu(); - await poFederationChannelServer2.content.btnOptionReplyInThread.click(); + await poFederationChannelServer2.content.openLastMessageMenu(); + await poFederationChannelServer2.content.btnOptionReplyInThread.click(); - await expect(pageForServer2).toHaveURL(/.*thread/); - await expect(poFederationChannelServer2.content.lastThreadMessageText).toContainText('This is a thread message sent from server A'); + await expect(pageForServer2).toHaveURL(/.*thread/); + await expect(poFederationChannelServer2.content.lastThreadMessageText).toContainText('This is a thread message sent from server A'); }); - }); + }); test.describe('Send "Special" messages', () => { test('expect to send a thread message with emojis from Server A to Server B', async ({ page }) => { @@ -145,18 +145,24 @@ test.describe.only('Federation - Threads', () => { await poFederationChannelServer2.sidenav.openChat(createdGroupName); await poFederationChannelServer1.content.sendMessage('hello world from server A'); - await poFederationChannelServer2.content.openLastMessageMenu(); - await poFederationChannelServer2.content.btnOptionReplyInThread.click(); + await poFederationChannelServer2.content.openLastMessageMenu(); + await poFederationChannelServer2.content.btnOptionReplyInThread.click(); await poFederationChannelServer2.content.sendThreadMessage('😀 😀 hello world 🌎 from server B with emojis 😀 😀'); - await expect(poFederationChannelServer2.content.lastThreadMessageText).toContainText('😀 😀 hello world 🌎 from server B with emojis 😀 😀'); - await expect(poFederationChannelServer2.content.lastUserMessage).toContainText('😀 😀 hello world 🌎 from server B with emojis 😀 😀'); + await expect(poFederationChannelServer2.content.lastThreadMessageText).toContainText( + '😀 😀 hello world 🌎 from server B with emojis 😀 😀', + ); + await expect(poFederationChannelServer2.content.lastUserMessage).toContainText( + '😀 😀 hello world 🌎 from server B with emojis 😀 😀', + ); - await poFederationChannelServer1.content.openLastMessageMenu(); - await poFederationChannelServer1.content.btnOptionReplyInThread.click(); + await poFederationChannelServer1.content.openLastMessageMenu(); + await poFederationChannelServer1.content.btnOptionReplyInThread.click(); - await expect(poFederationChannelServer1.content.lastThreadMessageText).toContainText('😀 😀 hello world 🌎 from server B with emojis 😀 😀'); + await expect(poFederationChannelServer1.content.lastThreadMessageText).toContainText( + '😀 😀 hello world 🌎 from server B with emojis 😀 😀', + ); }); test('expect to send a thread message with emojis from Server B to Server A', async ({ page }) => { @@ -167,18 +173,24 @@ test.describe.only('Federation - Threads', () => { await poFederationChannelServer2.sidenav.openChat(createdGroupName); await poFederationChannelServer2.content.sendMessage('hello world from server B'); - await poFederationChannelServer1.content.openLastMessageMenu(); - await poFederationChannelServer1.content.btnOptionReplyInThread.click(); + await poFederationChannelServer1.content.openLastMessageMenu(); + await poFederationChannelServer1.content.btnOptionReplyInThread.click(); await poFederationChannelServer1.content.sendThreadMessage('😀 😀 hello world 🌎 from server A with emojis 😀 😀'); - await expect(poFederationChannelServer1.content.lastThreadMessageText).toContainText('😀 😀 hello world 🌎 from server A with emojis 😀 😀'); - await expect(poFederationChannelServer1.content.lastUserMessage).toContainText('😀 😀 hello world 🌎 from server A with emojis 😀 😀'); + await expect(poFederationChannelServer1.content.lastThreadMessageText).toContainText( + '😀 😀 hello world 🌎 from server A with emojis 😀 😀', + ); + await expect(poFederationChannelServer1.content.lastUserMessage).toContainText( + '😀 😀 hello world 🌎 from server A with emojis 😀 😀', + ); - await poFederationChannelServer2.content.openLastMessageMenu(); - await poFederationChannelServer2.content.btnOptionReplyInThread.click(); + await poFederationChannelServer2.content.openLastMessageMenu(); + await poFederationChannelServer2.content.btnOptionReplyInThread.click(); - await expect(poFederationChannelServer2.content.lastThreadMessageText).toContainText('😀 😀 hello world 🌎 from server A with emojis 😀 😀'); + await expect(poFederationChannelServer2.content.lastThreadMessageText).toContainText( + '😀 😀 hello world 🌎 from server A with emojis 😀 😀', + ); }); test('expect to send an audio message from Server A to Server B', async ({ page }) => { @@ -189,22 +201,21 @@ test.describe.only('Federation - Threads', () => { await poFederationChannelServer2.sidenav.openChat(createdGroupName); await poFederationChannelServer1.content.sendMessage('hello world from server A'); - await poFederationChannelServer2.content.openLastMessageMenu(); - await poFederationChannelServer2.content.btnOptionReplyInThread.click(); + await poFederationChannelServer2.content.openLastMessageMenu(); + await poFederationChannelServer2.content.btnOptionReplyInThread.click(); await poFederationChannelServer2.content.sendAudioRecordedInThreadMessage(); - await expect(await (await poFederationChannelServer2.content.getLastFileThreadMessageByFileName('Audio record.mp3')).innerText()).toEqual( - 'Audio record.mp3', - ); + await expect( + await (await poFederationChannelServer2.content.getLastFileThreadMessageByFileName('Audio record.mp3')).innerText(), + ).toEqual('Audio record.mp3'); - await poFederationChannelServer1.content.openLastMessageMenu(); - await poFederationChannelServer1.content.btnOptionReplyInThread.click(); + await poFederationChannelServer1.content.openLastMessageMenu(); + await poFederationChannelServer1.content.btnOptionReplyInThread.click(); - - await expect(await (await poFederationChannelServer1.content.getLastFileThreadMessageByFileName('Audio record.mp3')).innerText()).toEqual( - 'Audio record.mp3', - ); + await expect( + await (await poFederationChannelServer1.content.getLastFileThreadMessageByFileName('Audio record.mp3')).innerText(), + ).toEqual('Audio record.mp3'); }); test('expect to send an audio message from Server B to Server A', async ({ page }) => { @@ -213,24 +224,23 @@ test.describe.only('Federation - Threads', () => { await poFederationChannelServer1.sidenav.openChat(createdGroupName); await poFederationChannelServer2.sidenav.openChat(createdGroupName); - await poFederationChannelServer2.content.sendMessage('hello world from server B'); + await poFederationChannelServer2.content.sendMessage('hello world from server B'); - await poFederationChannelServer1.content.openLastMessageMenu(); - await poFederationChannelServer1.content.btnOptionReplyInThread.click(); + await poFederationChannelServer1.content.openLastMessageMenu(); + await poFederationChannelServer1.content.btnOptionReplyInThread.click(); await poFederationChannelServer1.content.sendAudioRecordedInThreadMessage(); - await expect(await (await poFederationChannelServer1.content.getLastFileThreadMessageByFileName('Audio record.mp3')).innerText()).toEqual( - 'Audio record.mp3', - ); + await expect( + await (await poFederationChannelServer1.content.getLastFileThreadMessageByFileName('Audio record.mp3')).innerText(), + ).toEqual('Audio record.mp3'); - await poFederationChannelServer2.content.openLastMessageMenu(); - await poFederationChannelServer2.content.btnOptionReplyInThread.click(); + await poFederationChannelServer2.content.openLastMessageMenu(); + await poFederationChannelServer2.content.btnOptionReplyInThread.click(); - - await expect(await (await poFederationChannelServer2.content.getLastFileThreadMessageByFileName('Audio record.mp3')).innerText()).toEqual( - 'Audio record.mp3', - ); + await expect( + await (await poFederationChannelServer2.content.getLastFileThreadMessageByFileName('Audio record.mp3')).innerText(), + ).toEqual('Audio record.mp3'); }); test('expect to send a thread message mentioning an user from Server A to Server B', async ({ page }) => { @@ -239,19 +249,25 @@ test.describe.only('Federation - Threads', () => { await poFederationChannelServer1.sidenav.openChat(createdGroupName); await poFederationChannelServer2.sidenav.openChat(createdGroupName); - await poFederationChannelServer1.content.sendMessage('hello world from server A'); + await poFederationChannelServer1.content.sendMessage('hello world from server A'); - await poFederationChannelServer2.content.openLastMessageMenu(); - await poFederationChannelServer2.content.btnOptionReplyInThread.click(); + await poFederationChannelServer2.content.openLastMessageMenu(); + await poFederationChannelServer2.content.btnOptionReplyInThread.click(); - await poFederationChannelServer2.content.sendThreadMessage(`hello @${adminUsernameWithDomainFromServer1}, here's @${userFromServer2UsernameOnly} from Server B`); + await poFederationChannelServer2.content.sendThreadMessage( + `hello @${adminUsernameWithDomainFromServer1}, here's @${userFromServer2UsernameOnly} from Server B`, + ); - await expect(poFederationChannelServer2.content.lastThreadMessageText).toContainText(`hello ${adminUsernameWithDomainFromServer1}, here's ${userFromServer2UsernameOnly} from Server B`); + await expect(poFederationChannelServer2.content.lastThreadMessageText).toContainText( + `hello ${adminUsernameWithDomainFromServer1}, here's ${userFromServer2UsernameOnly} from Server B`, + ); - await poFederationChannelServer1.content.openLastMessageMenu(); - await poFederationChannelServer1.content.btnOptionReplyInThread.click(); + await poFederationChannelServer1.content.openLastMessageMenu(); + await poFederationChannelServer1.content.btnOptionReplyInThread.click(); - await expect(poFederationChannelServer1.content.lastThreadMessageText).toContainText(`hello ${constants.RC_SERVER_1.username}, here's ${usernameWithDomainFromServer2} from Server B`); + await expect(poFederationChannelServer1.content.lastThreadMessageText).toContainText( + `hello ${constants.RC_SERVER_1.username}, here's ${usernameWithDomainFromServer2} from Server B`, + ); }); test('expect to send a thread message mentioning an user Server B to Server A', async ({ page }) => { @@ -260,19 +276,25 @@ test.describe.only('Federation - Threads', () => { await poFederationChannelServer1.sidenav.openChat(createdGroupName); await poFederationChannelServer2.sidenav.openChat(createdGroupName); - await poFederationChannelServer2.content.sendMessage('hello world from server B'); + await poFederationChannelServer2.content.sendMessage('hello world from server B'); - await poFederationChannelServer1.content.openLastMessageMenu(); - await poFederationChannelServer1.content.btnOptionReplyInThread.click(); + await poFederationChannelServer1.content.openLastMessageMenu(); + await poFederationChannelServer1.content.btnOptionReplyInThread.click(); - await poFederationChannelServer1.content.sendThreadMessage(`hello @${usernameWithDomainFromServer2}, here's @${constants.RC_SERVER_1.username} from Server A`); + await poFederationChannelServer1.content.sendThreadMessage( + `hello @${usernameWithDomainFromServer2}, here's @${constants.RC_SERVER_1.username} from Server A`, + ); - await expect(poFederationChannelServer1.content.lastThreadMessageText).toContainText(`hello ${usernameWithDomainFromServer2}, here's ${constants.RC_SERVER_1.username} from Server A`); + await expect(poFederationChannelServer1.content.lastThreadMessageText).toContainText( + `hello ${usernameWithDomainFromServer2}, here's ${constants.RC_SERVER_1.username} from Server A`, + ); - await poFederationChannelServer2.content.openLastMessageMenu(); - await poFederationChannelServer2.content.btnOptionReplyInThread.click(); + await poFederationChannelServer2.content.openLastMessageMenu(); + await poFederationChannelServer2.content.btnOptionReplyInThread.click(); - await expect(poFederationChannelServer2.content.lastThreadMessageText).toContainText(`hello ${userFromServer2UsernameOnly}, here's ${adminUsernameWithDomainFromServer1} from Server A`); + await expect(poFederationChannelServer2.content.lastThreadMessageText).toContainText( + `hello ${userFromServer2UsernameOnly}, here's ${adminUsernameWithDomainFromServer1} from Server A`, + ); }); }); @@ -281,47 +303,47 @@ test.describe.only('Federation - Threads', () => { await page.goto(`${constants.RC_SERVER_1.url}/home`); await pageForServer2.goto(`${constants.RC_SERVER_2.url}/home`); - await poFederationChannelServer1.sidenav.openChat(createdGroupName); + await poFederationChannelServer1.sidenav.openChat(createdGroupName); await poFederationChannelServer2.sidenav.openChat(createdGroupName); - + const message = `Message for quote - ${Date.now()}`; - await poFederationChannelServer1.content.sendMessage('hello world from server A'); + await poFederationChannelServer1.content.sendMessage('hello world from server A'); - await poFederationChannelServer2.content.openLastMessageMenu(); - await poFederationChannelServer2.content.btnOptionReplyInThread.click(); + await poFederationChannelServer2.content.openLastMessageMenu(); + await poFederationChannelServer2.content.btnOptionReplyInThread.click(); await poFederationChannelServer2.content.sendThreadMessage(message); - - await poFederationChannelServer1.content.openLastMessageMenu(); - await poFederationChannelServer1.content.btnOptionReplyInThread.click(); + + await poFederationChannelServer1.content.openLastMessageMenu(); + await poFederationChannelServer1.content.btnOptionReplyInThread.click(); await poFederationChannelServer1.content.quoteMessageInsideThread('this is a quote message'); - await expect(poFederationChannelServer1.content.waitForLastThreadMessageTextAttachmentEqualsText).toContainText(message); - await expect(poFederationChannelServer2.content.waitForLastThreadMessageTextAttachmentEqualsText).toContainText(message); + await expect(poFederationChannelServer1.content.waitForLastThreadMessageTextAttachmentEqualsText).toContainText(message); + await expect(poFederationChannelServer2.content.waitForLastThreadMessageTextAttachmentEqualsText).toContainText(message); }); test('expect to send a thread message quoting a thread message Server B to Server A', async ({ page }) => { await page.goto(`${constants.RC_SERVER_1.url}/home`); await pageForServer2.goto(`${constants.RC_SERVER_2.url}/home`); - await poFederationChannelServer1.sidenav.openChat(createdGroupName); + await poFederationChannelServer1.sidenav.openChat(createdGroupName); await poFederationChannelServer2.sidenav.openChat(createdGroupName); - + const message = `Message for quote - ${Date.now()}`; - await poFederationChannelServer2.content.sendMessage('hello world from server B'); + await poFederationChannelServer2.content.sendMessage('hello world from server B'); - await poFederationChannelServer1.content.openLastMessageMenu(); - await poFederationChannelServer1.content.btnOptionReplyInThread.click(); + await poFederationChannelServer1.content.openLastMessageMenu(); + await poFederationChannelServer1.content.btnOptionReplyInThread.click(); await poFederationChannelServer1.content.sendThreadMessage(message); - - await poFederationChannelServer2.content.openLastMessageMenu(); - await poFederationChannelServer2.content.btnOptionReplyInThread.click(); + + await poFederationChannelServer2.content.openLastMessageMenu(); + await poFederationChannelServer2.content.btnOptionReplyInThread.click(); await poFederationChannelServer2.content.quoteMessageInsideThread('this is a quote message'); - await expect(poFederationChannelServer1.content.waitForLastThreadMessageTextAttachmentEqualsText).toContainText(message); - await expect(poFederationChannelServer2.content.waitForLastThreadMessageTextAttachmentEqualsText).toContainText(message); + await expect(poFederationChannelServer1.content.waitForLastThreadMessageTextAttachmentEqualsText).toContainText(message); + await expect(poFederationChannelServer2.content.waitForLastThreadMessageTextAttachmentEqualsText).toContainText(message); }); }); diff --git a/apps/meteor/tests/e2e/fixtures/files/number1.png b/apps/meteor/tests/e2e/fixtures/files/number1.png new file mode 100644 index 000000000000..4359ce188209 Binary files /dev/null and b/apps/meteor/tests/e2e/fixtures/files/number1.png differ diff --git a/apps/meteor/tests/e2e/fixtures/files/number2.png b/apps/meteor/tests/e2e/fixtures/files/number2.png new file mode 100644 index 000000000000..b4ed8a157166 Binary files /dev/null and b/apps/meteor/tests/e2e/fixtures/files/number2.png differ diff --git a/apps/meteor/tests/e2e/fixtures/files/number3.png b/apps/meteor/tests/e2e/fixtures/files/number3.png new file mode 100644 index 000000000000..7a29d4122125 Binary files /dev/null and b/apps/meteor/tests/e2e/fixtures/files/number3.png differ diff --git a/apps/meteor/tests/e2e/fixtures/files/number4.png b/apps/meteor/tests/e2e/fixtures/files/number4.png new file mode 100644 index 000000000000..7bd2b90faa94 Binary files /dev/null and b/apps/meteor/tests/e2e/fixtures/files/number4.png differ diff --git a/apps/meteor/tests/e2e/fixtures/files/number5.png b/apps/meteor/tests/e2e/fixtures/files/number5.png new file mode 100644 index 000000000000..0ea50958dfcd Binary files /dev/null and b/apps/meteor/tests/e2e/fixtures/files/number5.png differ diff --git a/apps/meteor/tests/e2e/fixtures/files/number6.png b/apps/meteor/tests/e2e/fixtures/files/number6.png new file mode 100644 index 000000000000..95e0d4248b3e Binary files /dev/null and b/apps/meteor/tests/e2e/fixtures/files/number6.png differ diff --git a/apps/meteor/tests/e2e/forgot-password.spec.ts b/apps/meteor/tests/e2e/forgot-password.spec.ts index 441944f5b227..8330f8c767e2 100644 --- a/apps/meteor/tests/e2e/forgot-password.spec.ts +++ b/apps/meteor/tests/e2e/forgot-password.spec.ts @@ -2,7 +2,7 @@ import { Registration } from './page-objects'; import { test, expect } from './utils/test'; test.describe.parallel('Forgot Password', () => { - let poRegistration: Registration; + let poRegistration: Registration; test.beforeEach(async ({ page }) => { poRegistration = new Registration(page); @@ -42,5 +42,5 @@ test.describe.parallel('Forgot Password', () => { test('should not have any accessibility violations', async ({ makeAxeBuilder }) => { const results = await makeAxeBuilder().analyze(); expect(results.violations).toEqual([]); - }) + }); }); diff --git a/apps/meteor/tests/e2e/homepage.spec.ts b/apps/meteor/tests/e2e/homepage.spec.ts index 89aa905744df..72291785bd09 100644 --- a/apps/meteor/tests/e2e/homepage.spec.ts +++ b/apps/meteor/tests/e2e/homepage.spec.ts @@ -49,9 +49,7 @@ test.describe.serial('homepage', () => { test('visibility and button functionality in custom body with empty custom content', async () => { await test.step('expect default value in custom body', async () => { - await expect( - adminPage.locator('div >> text="Admins may insert content html to be rendered in this white space."'), - ).toBeVisible(); + await expect(adminPage.locator('div >> text="Admins may insert content html to be rendered in this white space."')).toBeVisible(); }); await test.step('expect both change visibility and show only custom content buttons to be disabled', async () => { diff --git a/apps/meteor/tests/e2e/image-gallery.spec.ts b/apps/meteor/tests/e2e/image-gallery.spec.ts index e3a52d79f6bc..0291eefff9df 100644 --- a/apps/meteor/tests/e2e/image-gallery.spec.ts +++ b/apps/meteor/tests/e2e/image-gallery.spec.ts @@ -7,33 +7,48 @@ import { expect, test } from './utils/test'; test.describe.serial('Image Gallery', async () => { let poHomeChannel: HomeChannel; let targetChannel: string; + let targetChannelLargeImage: string; const viewport = { width: 1280, height: 720, }; + // Using more than 5 images so that new images need to be loaded by the gallery + const imageNames = ['number1.png', 'number2.png', 'number3.png', 'number4.png', 'number5.png', 'number6.png']; test.use({ viewport }); test.beforeAll(async ({ api, browser }) => { targetChannel = await createTargetChannel(api); + targetChannelLargeImage = await createTargetChannel(api); const { page } = await createAuxContext(browser, Users.user1); poHomeChannel = new HomeChannel(page); + await poHomeChannel.sidenav.openChat(targetChannelLargeImage); + await poHomeChannel.content.btnJoinRoom.click(); + await poHomeChannel.sidenav.openChat(targetChannel); await poHomeChannel.content.btnJoinRoom.click(); }); test.afterAll(async ({ api }) => { await deleteChannel(api, targetChannel); + await deleteChannel(api, targetChannelLargeImage); }); test.describe('When sending an image as a file', () => { - test.beforeAll(async() => { + test.beforeAll(async () => { + await poHomeChannel.sidenav.openChat(targetChannel); + for await (const imageName of imageNames) { + await poHomeChannel.content.sendFileMessage(imageName); + await poHomeChannel.content.btnModalConfirm.click(); + await expect(poHomeChannel.content.lastUserMessage).toContainText(imageName); + } + + await poHomeChannel.sidenav.openChat(targetChannelLargeImage); await poHomeChannel.content.sendFileMessage('test-large-image.jpeg'); await poHomeChannel.content.btnModalConfirm.click(); - await expect(poHomeChannel.content.lastUserMessage).toContainText('test-large-image.jpeg'); - + await poHomeChannel.content.lastUserMessage.locator('img.gallery-item').click(); }); @@ -41,51 +56,76 @@ test.describe.serial('Image Gallery', async () => { expect( await poHomeChannel.content.imageGalleryImage.evaluate((el) => parseInt(window.getComputedStyle(el).getPropertyValue('width'))), ).toBeLessThanOrEqual(viewport.width); - + expect( await poHomeChannel.content.imageGalleryImage.evaluate((el) => parseInt(window.getComputedStyle(el).getPropertyValue('height'))), ).toBeLessThanOrEqual(viewport.height); }); - + test('expect to zoom in image', async () => { await (await poHomeChannel.content.getGalleryButtonByName('zoom-in')).click(); - + expect(parseInt((await poHomeChannel.content.imageGalleryImage.getAttribute('data-qa-zoom-scale')) as string)).toBeGreaterThan(1); }); - + test('expect to zoom out image', async () => { await (await poHomeChannel.content.getGalleryButtonByName('zoom-out')).click(); - + expect(parseInt((await poHomeChannel.content.imageGalleryImage.getAttribute('data-qa-zoom-scale')) as string)).toEqual(1); }); - + test('expect to resize image to default ratio', async () => { await expect(await poHomeChannel.content.getGalleryButtonByName('zoom-out')).toBeDisabled(); - + await (await poHomeChannel.content.getGalleryButtonByName('zoom-in')).dblclick(); - + await expect(await poHomeChannel.content.getGalleryButtonByName('zoom-out')).toBeEnabled(); - + await (await poHomeChannel.content.getGalleryButtonByName('resize')).click(); - + expect(parseInt((await poHomeChannel.content.imageGalleryImage.getAttribute('data-qa-zoom-scale')) as string)).toEqual(1); }); - + test('expect to close gallery', async () => { await (await poHomeChannel.content.getGalleryButtonByName('close')).click(); - + await expect(poHomeChannel.content.imageGalleryImage).not.toBeVisible(); }); + + test('expect successfully move to older images by using the left arrow button', async () => { + await poHomeChannel.sidenav.openChat(targetChannel); + await poHomeChannel.content.lastUserMessage.locator('img.gallery-item').click(); + /* eslint-disable no-await-in-loop */ + for (let i = 0; i < imageNames.length - 1; i++) { + await expect(poHomeChannel.content.previousSlideButton).toBeEnabled(); + await expect(poHomeChannel.content.currentGalleryImage).toHaveAttribute( + 'src', + new RegExp(`${imageNames[imageNames.length - (i + 1)]}$`), + ); + await poHomeChannel.content.previousSlideButton.click(); + } + await expect(poHomeChannel.content.previousSlideButton).toBeDisabled(); + }); + + test('expect successfully move to newer images by using the right arrow button', async () => { + for (let i = 0; i < imageNames.length - 1; i++) { + await expect(poHomeChannel.content.nextSlideButton).toBeEnabled(); + await expect(poHomeChannel.content.currentGalleryImage).toHaveAttribute('src', new RegExp(`${imageNames[i]}$`)); + await poHomeChannel.content.nextSlideButton.click(); + } + await expect(poHomeChannel.content.nextSlideButton).toBeDisabled(); + await (await poHomeChannel.content.getGalleryButtonByName('close')).click(); + }); }); test.describe('When sending an image as a link', () => { const imageLink = 'https://i0.wp.com/merithu.com.br/wp-content/uploads/2019/11/rocket-chat.png'; - test.beforeAll(async() => { + test.beforeAll(async () => { await poHomeChannel.content.sendMessage(imageLink); - + await expect(poHomeChannel.content.lastUserMessage).toContainText(imageLink); - + await poHomeChannel.content.lastUserMessage.locator('img.preview-image').click(); }); diff --git a/apps/meteor/tests/e2e/imports.spec.ts b/apps/meteor/tests/e2e/imports.spec.ts index 5b7c54316758..6da86cee86f9 100644 --- a/apps/meteor/tests/e2e/imports.spec.ts +++ b/apps/meteor/tests/e2e/imports.spec.ts @@ -31,39 +31,42 @@ const dmMessagesCsvDir = path.resolve(__dirname, 'fixtures', 'files', 'dm_messag const usersCsvsToJson = async (): Promise => { await new Promise((resolve) => - fs.createReadStream(slackCsvDir) + fs + .createReadStream(slackCsvDir) .pipe(parse({ delimiter: ',', from_line: 2 })) .on('data', (rows) => { rowUserName.push(rows[0]); }) - .on('end', resolve) + .on('end', resolve), ); await new Promise((resolve) => - fs.createReadStream(usersCsvDir) + fs + .createReadStream(usersCsvDir) .pipe(parse({ delimiter: ',' })) .on('data', (rows) => { rowUserName.push(rows[0]); csvImportedUsernames.push(rows[0]); }) - .on('end', resolve) + .on('end', resolve), ); }; -const countDmMessages = (): Promise => ( +const countDmMessages = (): Promise => new Promise((resolve) => - fs.createReadStream(dmMessagesCsvDir) + fs + .createReadStream(dmMessagesCsvDir) .pipe(parse({ delimiter: ',' })) .on('data', (rows) => { dmMessages.push(rows[3]); }) - .on('end', resolve) - ) -); + .on('end', resolve), + ); -const roomsCsvToJson = (): Promise => ( +const roomsCsvToJson = (): Promise => new Promise((resolve) => - fs.createReadStream(roomsCsvDir) + fs + .createReadStream(roomsCsvDir) .pipe(parse({ delimiter: ',' })) .on('data', (rows) => { importedRooms.push({ @@ -73,9 +76,8 @@ const roomsCsvToJson = (): Promise => ( members: rows[3], }); }) - .on('end', resolve) - ) -); + .on('end', resolve), + ); test.describe.serial('imports', () => { test.beforeAll(async () => { @@ -136,7 +138,7 @@ test.describe.serial('imports', () => { await poAdmin.inputSearchRooms.fill(room.name); const expectedMembersCount = room.members.split(';').filter((username) => username !== room.ownerUsername).length + 1; - expect(page.locator(`tbody tr td:nth-child(2) >> text="${ expectedMembersCount }"`)); + expect(page.locator(`tbody tr td:nth-child(2) >> text="${expectedMembersCount}"`)); } }); @@ -148,7 +150,9 @@ test.describe.serial('imports', () => { await poAdmin.inputSearchRooms.fill(room.name); await poAdmin.getRoomRow(room.name).click(); - room.visibility === 'private' ? await expect(poAdmin.privateInput).toBeChecked() : await expect(poAdmin.privateInput).not.toBeChecked(); + room.visibility === 'private' + ? await expect(poAdmin.privateInput).toBeChecked() + : await expect(poAdmin.privateInput).not.toBeChecked(); await expect(poAdmin.roomOwnerInput).toHaveValue(room.ownerUsername); } }); @@ -162,10 +166,10 @@ test.describe.serial('imports', () => { expect(page.locator(`tbody tr td:first-child >> text="${user}"`)); const expectedMembersCount = 2; - expect(page.locator(`tbody tr td:nth-child(2) >> text="${ expectedMembersCount }"`)); + expect(page.locator(`tbody tr td:nth-child(2) >> text="${expectedMembersCount}"`)); const expectedMessagesCount = dmMessages.length; - expect(page.locator(`tbody tr td:nth-child(3) >> text="${ expectedMessagesCount }"`)); - } + expect(page.locator(`tbody tr td:nth-child(3) >> text="${expectedMessagesCount}"`)); + } }); }); diff --git a/apps/meteor/tests/e2e/login.spec.ts b/apps/meteor/tests/e2e/login.spec.ts index 41710fffa203..63e4949c31d9 100644 --- a/apps/meteor/tests/e2e/login.spec.ts +++ b/apps/meteor/tests/e2e/login.spec.ts @@ -18,7 +18,7 @@ test.describe.parallel('Login', () => { test('should not have any accessibility violations', async ({ makeAxeBuilder }) => { const results = await makeAxeBuilder().analyze(); expect(results.violations).toEqual([]); - }) + }); test('Login with invalid credentials', async () => { await test.step('expect to have username and password marked as invalid', async () => { diff --git a/apps/meteor/tests/e2e/message-actions.spec.ts b/apps/meteor/tests/e2e/message-actions.spec.ts index 259ab4d71d33..5186d27e3656 100644 --- a/apps/meteor/tests/e2e/message-actions.spec.ts +++ b/apps/meteor/tests/e2e/message-actions.spec.ts @@ -86,7 +86,7 @@ test.describe.serial('message-actions', () => { await poHomeChannel.content.openLastMessageMenu(); await page.locator('role=menuitem[name="Copy text"]').click(); - const clipboardText = await page.evaluate("navigator.clipboard.readText()"); + const clipboardText = await page.evaluate('navigator.clipboard.readText()'); expect(clipboardText).toBe('Message to copy'); }); @@ -128,7 +128,7 @@ test.describe.serial('message-actions', () => { await poHomeChannel.sidenav.openChat(forwardChannel); await expect(poHomeChannel.content.lastUserMessage).toContainText(message); - }) + }); test('expect forward message to team', async () => { const message = 'this is a message to forward to team'; @@ -137,7 +137,7 @@ test.describe.serial('message-actions', () => { await poHomeChannel.sidenav.openChat(forwardTeam); await expect(poHomeChannel.content.lastUserMessage).toContainText(message); - }) + }); test('expect forward message to direct message', async () => { const message = 'this is a message to forward to direct message'; @@ -149,7 +149,7 @@ test.describe.serial('message-actions', () => { await poHomeChannel.sidenav.openChat(ADMIN_CREDENTIALS.username); await expect(poHomeChannel.content.lastUserMessage).toContainText(message); - }) + }); test('expect forward text file to channel', async () => { const filename = 'any_file.txt'; @@ -161,7 +161,7 @@ test.describe.serial('message-actions', () => { await poHomeChannel.sidenav.openChat(forwardChannel); await expect(poHomeChannel.content.lastUserMessage).toContainText(filename); - }) + }); test('expect forward image file to channel', async () => { const filename = 'test-image.jpeg'; @@ -173,7 +173,7 @@ test.describe.serial('message-actions', () => { await poHomeChannel.sidenav.openChat(forwardChannel); await expect(poHomeChannel.content.lastUserMessage).toContainText(filename); - }) + }); test('expect forward pdf file to channel', async () => { const filename = 'test_pdf_file.pdf'; @@ -185,7 +185,7 @@ test.describe.serial('message-actions', () => { await poHomeChannel.sidenav.openChat(forwardChannel); await expect(poHomeChannel.content.lastUserMessage).toContainText(filename); - }) + }); test('expect forward audio message to channel', async () => { const filename = 'sample-audio.mp3'; @@ -197,7 +197,7 @@ test.describe.serial('message-actions', () => { await poHomeChannel.sidenav.openChat(forwardChannel); await expect(poHomeChannel.content.lastUserMessage).toContainText(filename); - }) + }); test('expect forward video message to channel', async () => { const filename = 'test_video.mp4'; @@ -209,5 +209,5 @@ test.describe.serial('message-actions', () => { await poHomeChannel.sidenav.openChat(forwardChannel); await expect(poHomeChannel.content.lastUserMessage).toContainText(filename); - }) + }); }); diff --git a/apps/meteor/tests/e2e/message-composer.spec.ts b/apps/meteor/tests/e2e/message-composer.spec.ts index 8b8888c040a2..e68d82daf78f 100644 --- a/apps/meteor/tests/e2e/message-composer.spec.ts +++ b/apps/meteor/tests/e2e/message-composer.spec.ts @@ -52,7 +52,7 @@ test.describe.serial('message-composer', () => { await page.keyboard.press('Tab'); await page.keyboard.press('Tab'); - + await expect(poHomeChannel.composerToolbar.getByRole('button', { name: 'Emoji' })).not.toBeFocused(); }); @@ -63,10 +63,10 @@ test.describe.serial('message-composer', () => { await page.keyboard.type('hello composer'); await page.keyboard.press('Control+A'); // on Windows and Linux await page.keyboard.press('Meta+A'); // on macOS - await poHomeChannel.composerToolbar.getByRole('button', { name: 'Link' }).click() + await poHomeChannel.composerToolbar.getByRole('button', { name: 'Link' }).click(); await page.keyboard.type(url); await page.keyboard.press('Enter'); - + await expect(poHomeChannel.composer).toHaveValue(`[hello composer](${url})`); }); }); diff --git a/apps/meteor/tests/e2e/message-mentions.spec.ts b/apps/meteor/tests/e2e/message-mentions.spec.ts index 1d956dfcb735..1b5b7e1bb6fc 100644 --- a/apps/meteor/tests/e2e/message-mentions.spec.ts +++ b/apps/meteor/tests/e2e/message-mentions.spec.ts @@ -5,7 +5,6 @@ import { HomeChannel } from './page-objects'; import { createTargetPrivateChannel, createTargetTeam, deleteChannel, deleteTeam } from './utils'; import { test, expect } from './utils/test'; - test.use({ storageState: Users.admin.state }); const getMentionText = (username: string, kind?: number): string => { @@ -41,11 +40,15 @@ test.describe.serial('message-mentions', () => { test.describe('Should not allow to send @all mention if permission to do so is disabled', () => { let targetChannel2: string; test.beforeAll(async ({ api }) => { - expect((await api.post('/permissions.update', { permissions: [{ '_id': 'mention-all', 'roles': [] }] })).status()).toBe(200); + expect((await api.post('/permissions.update', { permissions: [{ _id: 'mention-all', roles: [] }] })).status()).toBe(200); }); test.afterAll(async ({ api }) => { - expect((await api.post('/permissions.update', { permissions: [{ '_id': 'mention-all', 'roles': ['admin', 'owner', 'moderator', 'user'] }] })).status()).toBe(200); + expect( + ( + await api.post('/permissions.update', { permissions: [{ _id: 'mention-all', roles: ['admin', 'owner', 'moderator', 'user'] }] }) + ).status(), + ).toBe(200); await deleteChannel(api, targetChannel2); }); @@ -72,11 +75,15 @@ test.describe.serial('message-mentions', () => { test.describe('Should not allow to send @here mention if permission to do so is disabled', () => { let targetChannel2: string; test.beforeAll(async ({ api }) => { - expect((await api.post('/permissions.update', { permissions: [{ '_id': 'mention-here', 'roles': [] }] })).status()).toBe(200); + expect((await api.post('/permissions.update', { permissions: [{ _id: 'mention-here', roles: [] }] })).status()).toBe(200); }); test.afterAll(async ({ api }) => { - expect((await api.post('/permissions.update', { permissions: [{ '_id': 'mention-here', 'roles': ['admin', 'owner', 'moderator', 'user'] }] })).status()).toBe(200); + expect( + ( + await api.post('/permissions.update', { permissions: [{ _id: 'mention-here', roles: ['admin', 'owner', 'moderator', 'user'] }] }) + ).status(), + ).toBe(200); await deleteChannel(api, targetChannel2); }); @@ -191,16 +198,18 @@ test.describe.serial('message-mentions', () => { await expect(userPage.content.lastUserMessageBody).toContainText(getMentionText(Users.user2.data.username, 3)); }); }); - }) + }); test.describe(() => { test.use({ storageState: Users.user1.state }); test.beforeAll(async ({ api }) => { - expect((await api.post('/permissions.update', { permissions: [{ '_id': 'create-d', 'roles': ['admin'] }] })).status()).toBe(200); + expect((await api.post('/permissions.update', { permissions: [{ _id: 'create-d', roles: ['admin'] }] })).status()).toBe(200); }); test.afterAll(async ({ api }) => { - expect((await api.post('/permissions.update', { permissions: [{ '_id': 'create-d', 'roles': ['admin', 'user', 'bot', 'app'] }] })).status()).toBe(200); + expect( + (await api.post('/permissions.update', { permissions: [{ _id: 'create-d', roles: ['admin', 'user', 'bot', 'app'] }] })).status(), + ).toBe(200); }); test('dismiss and add users actions', async ({ page }) => { @@ -215,7 +224,7 @@ test.describe.serial('message-mentions', () => { await poHomeChannel.sidenav.btnCreate.click(); await expect(page).toHaveURL(`/group/${targetChannel2}`); - }) + }); await test.step('receive bot message', async () => { await userPage.sidenav.openChat(targetChannel2); @@ -251,11 +260,13 @@ test.describe.serial('message-mentions', () => { test.describe(() => { test.use({ storageState: Users.user2.state }); test.beforeAll(async ({ api }) => { - expect((await api.post('/permissions.update', { permissions: [{ '_id': 'create-d', 'roles': ['admin'] }] })).status()).toBe(200); + expect((await api.post('/permissions.update', { permissions: [{ _id: 'create-d', roles: ['admin'] }] })).status()).toBe(200); }); test.afterAll(async ({ api }) => { - expect((await api.post('/permissions.update', { permissions: [{ '_id': 'create-d', 'roles': ['admin', 'user', 'bot', 'app'] }] })).status()).toBe(200); + expect( + (await api.post('/permissions.update', { permissions: [{ _id: 'create-d', roles: ['admin', 'user', 'bot', 'app'] }] })).status(), + ).toBe(200); }); test('no actions', async ({ page }) => { const userPage = new HomeChannel(page); @@ -263,7 +274,9 @@ test.describe.serial('message-mentions', () => { await test.step('receive bot message', async () => { await userPage.sidenav.openChat(targetChannel2); await userPage.content.sendMessage(getMentionText(Users.user3.data.username)); - await expect(userPage.content.lastUserMessage.locator('.rcx-message-block')).toContainText(getMentionText(Users.user3.data.username, 2)); + await expect(userPage.content.lastUserMessage.locator('.rcx-message-block')).toContainText( + getMentionText(Users.user3.data.username, 2), + ); }); await test.step('not show "Do nothing" action', async () => { @@ -276,7 +289,7 @@ test.describe.serial('message-mentions', () => { await expect(userPage.content.lastUserMessage.locator('button >> text="Let them know"')).not.toBeVisible(); }); }); - }) + }); test.describe('team mention', () => { let team: string; @@ -297,9 +310,7 @@ test.describe.serial('message-mentions', () => { await userPage.content.sendMessage(getMentionText(team)); await expect(userPage.content.lastUserMessage.locator('.rcx-message-block')).not.toBeVisible(); }); - }); - }) - - }) + }); + }); }); diff --git a/apps/meteor/tests/e2e/messaging.spec.ts b/apps/meteor/tests/e2e/messaging.spec.ts index 226b75ecc9a8..c5b004faeb85 100644 --- a/apps/meteor/tests/e2e/messaging.spec.ts +++ b/apps/meteor/tests/e2e/messaging.spec.ts @@ -49,15 +49,28 @@ test.describe.serial('Messaging', () => { await expect(page.locator('[data-qa-type="message"]:has-text("msg1")')).toBeFocused(); // move focus to the message toolbar - await page.locator('[data-qa-type="message"]:has-text("msg1")').locator('[role=toolbar][aria-label="Message actions"]').getByRole('button', { name: 'Add reaction' }).waitFor(); - + await page + .locator('[data-qa-type="message"]:has-text("msg1")') + .locator('[role=toolbar][aria-label="Message actions"]') + .getByRole('button', { name: 'Add reaction' }) + .waitFor(); + await page.keyboard.press('Tab'); await page.keyboard.press('Tab'); - await expect(page.locator('[data-qa-type="message"]:has-text("msg1")').locator('[role=toolbar][aria-label="Message actions"]').getByRole('button', { name: 'Add reaction' })).toBeFocused(); - + await expect( + page + .locator('[data-qa-type="message"]:has-text("msg1")') + .locator('[role=toolbar][aria-label="Message actions"]') + .getByRole('button', { name: 'Add reaction' }), + ).toBeFocused(); + // move focus to the composer await page.keyboard.press('Tab'); - await page.locator('[data-qa-type="message"]:has-text("msg2")').locator('[role=toolbar][aria-label="Message actions"]').getByRole('button', { name: 'Add reaction' }).waitFor(); + await page + .locator('[data-qa-type="message"]:has-text("msg2")') + .locator('[role=toolbar][aria-label="Message actions"]') + .getByRole('button', { name: 'Add reaction' }) + .waitFor(); await page.keyboard.press('Tab'); await page.keyboard.press('Tab'); await expect(poHomeChannel.composer).toBeFocused(); @@ -87,11 +100,11 @@ test.describe.serial('Messaging', () => { await page.keyboard.press('Tab'); await page.keyboard.press('Space'); await expect(poHomeChannel.userCardToolbar).not.toBeVisible(); - }) + }); test('should not restore focus on the last focused if it was triggered by click', async ({ page }) => { await poHomeChannel.sidenav.openChat(targetChannel); - await page.locator('[data-qa-type="message"]:has-text("msg1")').click(); + await page.locator('[data-qa-type="message"]:has-text("msg1")').click(); await poHomeChannel.composer.click(); await page.keyboard.press('Shift+Tab'); @@ -100,7 +113,7 @@ test.describe.serial('Messaging', () => { test('should not focus on the last message when focusing by click', async ({ page }) => { await poHomeChannel.sidenav.openChat(targetChannel); - await page.locator('[data-qa-type="message"]:has-text("msg1")').click(); + await page.locator('[data-qa-type="message"]:has-text("msg1")').click(); await expect(page.locator('[data-qa-type="message"]').last()).not.toBeFocused(); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-chat-transfers.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-chat-transfers.spec.ts index fd5715c691fe..101308ef0b6a 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-chat-transfers.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-chat-transfers.spec.ts @@ -1,4 +1,4 @@ -import { Page } from '@playwright/test'; +import type { Page } from '@playwright/test'; import { IS_EE } from '../config/constants'; import { createAuxContext } from '../fixtures/createAuxContext'; diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-current-chats.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-current-chats.spec.ts index 163a0f40f2b3..be8ec38a49aa 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-current-chats.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-current-chats.spec.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { Page } from '@playwright/test'; +import type { Page } from '@playwright/test'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-api.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-api.spec.ts index db2a0c63678c..bf77840446dc 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-api.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-api.spec.ts @@ -431,7 +431,7 @@ test.describe('OC - Livechat API', () => { await expect(poLiveChat.txtChatMessage('this_a_test_message_from_visitor_1')).toBeVisible(); // wait for load messages to happen - await page.waitForResponse(response => response.url().includes(`token=${registerGuestVisitor1.token}`)); + await page.waitForResponse((response) => response.url().includes(`token=${registerGuestVisitor1.token}`)); }); await test.step('Expect registerGuest to create guest 2', async () => { @@ -441,9 +441,12 @@ test.describe('OC - Livechat API', () => { ); // wait for load messages to happen - await page.waitForResponse(response => response.url().includes(`token=${registerGuestVisitor2.token}`)); + await page.waitForResponse((response) => response.url().includes(`token=${registerGuestVisitor2.token}`)); - await poLiveChat.page.frameLocator('#rocketchat-iframe').getByText('this_a_test_message_from_visitor_1').waitFor({ state: 'hidden' }); + await poLiveChat.page + .frameLocator('#rocketchat-iframe') + .getByText('this_a_test_message_from_visitor_1') + .waitFor({ state: 'hidden' }); await expect(poLiveChat.page.frameLocator('#rocketchat-iframe').getByText('Start Chat')).not.toBeVisible(); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-avatar-visibility.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-avatar-visibility.spec.ts index ec54ee6421ae..d2b1db457ba1 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-avatar-visibility.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-avatar-visibility.spec.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { Page } from '@playwright/test'; +import type { Page } from '@playwright/test'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-department.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-department.spec.ts index c0b2bf8ae852..d71467a9336c 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-department.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-department.spec.ts @@ -8,8 +8,6 @@ import { createAgent } from '../utils/omnichannel/agents'; import { addAgentToDepartment, createDepartment } from '../utils/omnichannel/departments'; import { test, expect } from '../utils/test'; - - test.use({ storageState: Users.user1.state }); test.describe('OC - Livechat - Department Flow', () => { @@ -64,7 +62,6 @@ test.describe('OC - Livechat - Department Flow', () => { }); test('OC - Livechat - Chat with Department', async () => { - const guest = { name: `${faker.person.firstName()} ${faker.string.nanoid(10)}}`, email: faker.internet.email(), @@ -92,11 +89,9 @@ test.describe('OC - Livechat - Department Flow', () => { }); test('OC - Livechat - Change Department', async () => { - const guest = { name: `${faker.person.firstName()} ${faker.string.nanoid(10)}}`, email: faker.internet.email(), - }; await test.step('expect start Chat with department', async () => { await poLiveChat.openAnyLiveChat(); @@ -133,7 +128,7 @@ test.describe('OC - Livechat - Department Flow', () => { await expect(poLiveChat.livechatModalText('Are you sure you want to switch the department?')).toBeVisible(); await poLiveChat.btnYes.click(); - + await expect(poLiveChat.livechatModal).toBeVisible(); await expect(poLiveChat.livechatModalText('Department switched')).toBeVisible(); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-fileupload.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-fileupload.spec.ts index a79f2c04c044..b1244e7813b7 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-fileupload.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-fileupload.spec.ts @@ -9,14 +9,17 @@ import { test, expect } from '../utils/test'; const visitor = { name: `${faker.person.firstName()} ${faker.string.uuid()}}`, email: faker.internet.email(), -} +}; // Endpoint defaults are reset after each test, so if not in matrix assume is true const endpointMatrix = [ - [{ url: '/settings/FileUpload_Enabled', value: false}], - [{ url: '/settings/Livechat_fileupload_enabled', value: false}], - [{ url: '/settings/FileUpload_Enabled', value: false}, { url: '/settings/Livechat_fileupload_enabled', value: false}], -] + [{ url: '/settings/FileUpload_Enabled', value: false }], + [{ url: '/settings/Livechat_fileupload_enabled', value: false }], + [ + { url: '/settings/FileUpload_Enabled', value: false }, + { url: '/settings/Livechat_fileupload_enabled', value: false }, + ], +]; const beforeTest = async (poLiveChat: OmnichannelLiveChat) => { await poLiveChat.page.goto('/livechat'); @@ -26,8 +29,8 @@ const beforeTest = async (poLiveChat: OmnichannelLiveChat) => { await poLiveChat.onlineAgentMessage.fill('this_a_test_message_from_user'); await poLiveChat.btnSendMessageToOnlineAgent.click(); - await poLiveChat.txtChatMessage('this_a_test_message_from_user').waitFor({state: 'visible'}); -} + await poLiveChat.txtChatMessage('this_a_test_message_from_user').waitFor({ state: 'visible' }); +}; test.describe('OC - Livechat - OC - File Upload', () => { let poLiveChat: OmnichannelLiveChat; @@ -45,7 +48,7 @@ test.describe('OC - Livechat - OC - File Upload', () => { poLiveChat = new OmnichannelLiveChat(page, api); }); - test.afterAll(async ({api}) => { + test.afterAll(async ({ api }) => { await api.post('/settings/FileUpload_Enabled', { value: true }); await api.post('/settings/Livechat_fileupload_enabled', { value: true }); @@ -85,7 +88,7 @@ test.describe('OC - Livechat - OC - File Upload - Disabled', () => { poHomeOmnichannel = new HomeOmnichannel(page); }); - test.afterAll(async ({api}) => { + test.afterAll(async ({ api }) => { await api.post('/settings/FileUpload_Enabled', { value: true }); await api.post('/settings/Livechat_fileupload_enabled', { value: true }); @@ -99,9 +102,11 @@ test.describe('OC - Livechat - OC - File Upload - Disabled', () => { test(`OC - Livechat - txt Drag & Drop - ${testName}`, async ({ page, api }) => { poLiveChat = new OmnichannelLiveChat(page, api); - await Promise.all(endpoints.map(async (endpoint: { url: string, value: boolean }) => { - await api.post(endpoint.url, { value: endpoint.value }); - })); + await Promise.all( + endpoints.map(async (endpoint: { url: string; value: boolean }) => { + await api.post(endpoint.url, { value: endpoint.value }); + }), + ); await poLiveChat.page.goto('/livechat'); @@ -110,7 +115,7 @@ test.describe('OC - Livechat - OC - File Upload - Disabled', () => { await poLiveChat.onlineAgentMessage.fill('this_a_test_message_from_user'); await poLiveChat.btnSendMessageToOnlineAgent.click(); - await poLiveChat.txtChatMessage('this_a_test_message_from_user').waitFor({state: 'visible'}); + await poLiveChat.txtChatMessage('this_a_test_message_from_user').waitFor({ state: 'visible' }); await test.step('expect to upload a txt file', async () => { await poLiveChat.dragAndDropTxtFile(); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-message-bubble-color.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-message-bubble-color.spec.ts index fa72d7406816..bc167a299494 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-message-bubble-color.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-message-bubble-color.spec.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { Page } from '@playwright/test'; +import type { Page } from '@playwright/test'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-tab-communication.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-tab-communication.spec.ts index 27c800fd0a5f..60e2e193262b 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-tab-communication.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-tab-communication.spec.ts @@ -9,7 +9,7 @@ import { test, expect } from '../utils/test'; test.describe('OC - Livechat - Cross Tab Communication', () => { let pageLivechat1: OmnichannelLiveChat; let pageLivechat2: OmnichannelLiveChat; - + let poHomeOmnichannel: HomeOmnichannel; let agent: Awaited>; @@ -53,7 +53,7 @@ test.describe('OC - Livechat - Cross Tab Communication', () => { await pageLivechat1.btnSendMessageToOnlineAgent.click(); await expect(pageLivechat1.page.locator('div >> text="this_a_test_message_from_user"')).toBeVisible(); - + await expect(pageLivechat2.page.locator('div >> text="this_a_test_message_from_user"')).toBeVisible(); }); @@ -72,11 +72,9 @@ test.describe('OC - Livechat - Cross Tab Communication', () => { await pageLivechat1.onlineAgentMessage.fill('this_a_test_message_from_user_after_close'); await pageLivechat1.btnSendMessageToOnlineAgent.click(); - await pageLivechat1.page.locator('div >> text="this_a_test_message_from_user"').waitFor({ state: 'hidden' }); await pageLivechat2.page.locator('div >> text="this_a_test_message_from_user"').waitFor({ state: 'hidden' }); - - + await expect(pageLivechat1.page.locator('div >> text="this_a_test_message_from_user"')).not.toBeVisible(); await expect(pageLivechat2.page.locator('div >> text="this_a_test_message_from_user"')).not.toBeVisible(); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat.spec.ts index 35629880e749..00823cd98a19 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat.spec.ts @@ -278,7 +278,7 @@ test.describe('OC - Livechat - Livechat_Display_Offline_Form', () => { test('OC - Livechat - Livechat_Display_Offline_Form false', async () => { await test.step('expect offline form to not be visible', async () => { await poLiveChat.openAnyLiveChat(); - await expect (poLiveChat.page.locator(`div >> text=${message}`)).toBeVisible(); + await expect(poLiveChat.page.locator(`div >> text=${message}`)).toBeVisible(); await expect(poLiveChat.textAreaMessage).not.toBeVisible(); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-manager-role.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-manager-role.spec.ts index a07f0e7b808f..a9c0de65cdff 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-manager-role.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-manager-role.spec.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { Page } from '@playwright/test'; +import type { Page } from '@playwright/test'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-manual-selection-logout.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-manual-selection-logout.spec.ts index ed16c9ac3a69..9fbb567e3a87 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-manual-selection-logout.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-manual-selection-logout.spec.ts @@ -1,4 +1,4 @@ -import { Page } from '@playwright/test'; +import type { Page } from '@playwright/test'; import { DEFAULT_USER_CREDENTIALS } from '../config/constants'; import injectInitialData from '../fixtures/inject-initial-data'; @@ -42,16 +42,18 @@ test.describe('OC - Manual Selection After Relogin', () => { // Delete all data test.afterAll(async ({ api }) => { - await agent.delete() + await agent.delete(); await api.post('/settings/Livechat_Routing_Method', { value: 'Auto_Selection' }); await injectInitialData(); }); test('OC - Manual Selection - Logout & Login', async ({ api }) => { expect(await poOmnichannel.page.locator('#omnichannel-status-toggle').getAttribute('title')).toEqual('Turn off answer chats'); - - const { data: { room } } = await createConversation(api); - + + const { + data: { room }, + } = await createConversation(api); + await test.step('expect login and see the chat in queue after login', async () => { await poOmnichannel.sidenav.getSidebarItemByName(room.fname).click(); await expect(poOmnichannel.content.inputMessage).not.toBeVisible(); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-manual-selection.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-manual-selection.spec.ts index 12443722160a..8a4e74c1661a 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-manual-selection.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-manual-selection.spec.ts @@ -1,4 +1,4 @@ -import { Page } from '@playwright/test'; +import type { Page } from '@playwright/test'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; @@ -43,13 +43,15 @@ test.describe('OC - Manual Selection', () => { test.afterAll(async ({ api }) => { await Promise.all([ agentB.page.close(), - ...agents.map(agent => agent.delete()), + ...agents.map((agent) => agent.delete()), api.post('/settings/Livechat_Routing_Method', { value: 'Auto_Selection' }), ]); }); test('OC - Manual Selection - Queue', async ({ page, api }) => { - const { data: { room } } = await createConversation(api); + const { + data: { room }, + } = await createConversation(api); await test.step('expect not be able to see queue when livechat is disabled', async () => { await poOmnichannel.sidenav.switchOmnichannelStatus('offline'); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-monitor-role.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-monitor-role.spec.ts index 3d4469a76b08..25a5336742a3 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-monitor-role.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-monitor-role.spec.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { Page } from '@playwright/test'; +import type { Page } from '@playwright/test'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-reports.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-reports.spec.ts index 10e4db2cfd0b..f336bf7eab62 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-reports.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-reports.spec.ts @@ -1,4 +1,4 @@ -import { Route } from '@playwright/test'; +import type { Route } from '@playwright/test'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-tags.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-tags.spec.ts index 4ad7bde6d760..f14cf6c37445 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-tags.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-tags.spec.ts @@ -12,7 +12,7 @@ import { test, expect } from '../utils/test'; test.use({ storageState: Users.admin.state }); test.describe('OC - Manage Tags', () => { - test.skip(!IS_EE, 'OC - Manage Tags > Enterprise Edition Only'); + test.skip(!IS_EE, 'OC - Manage Tags > Enterprise Edition Only'); let poOmnichannelTags: OmnichannelTags; @@ -34,17 +34,17 @@ test.describe('OC - Manage Tags', () => { await agent.delete(); }); - test.beforeEach(async ({ page }: { page: Page }) => { + test.beforeEach(async ({ page }: { page: Page }) => { poOmnichannelTags = new OmnichannelTags(page); }); - test('OC - Manage Tags - Create Tag', async ({ page }) => { - const tagName = faker.string.uuid(); + test('OC - Manage Tags - Create Tag', async ({ page }) => { + const tagName = faker.string.uuid(); - await page.goto('/omnichannel'); + await page.goto('/omnichannel'); await poOmnichannelTags.sidenav.linkTags.click(); - await test.step('expect correct form default state', async () => { + await test.step('expect correct form default state', async () => { await poOmnichannelTags.btnCreateTag.click(); await expect(poOmnichannelTags.contextualBar).toBeVisible(); await expect(poOmnichannelTags.btnSave).toBeDisabled(); @@ -53,7 +53,7 @@ test.describe('OC - Manage Tags', () => { await expect(poOmnichannelTags.contextualBar).not.toBeVisible(); }); - await test.step('expect to create new tag', async () => { + await test.step('expect to create new tag', async () => { await poOmnichannelTags.btnCreateTag.click(); await poOmnichannelTags.inputName.fill(tagName); await poOmnichannelTags.selectDepartment(department.data); @@ -66,7 +66,7 @@ test.describe('OC - Manage Tags', () => { }); }); - await test.step('expect to delete tag', async () => { + await test.step('expect to delete tag', async () => { await test.step('expect to be able to cancel delete', async () => { await poOmnichannelTags.btnDeleteByName(tagName).click(); await expect(poOmnichannelTags.confirmDeleteModal).toBeVisible(); @@ -82,9 +82,9 @@ test.describe('OC - Manage Tags', () => { await expect(page.locator('h3 >> text="No results found"')).toBeVisible(); }); }); - }); + }); - test('OC - Manage Tags - Edit tag departments', async ({ api, page }) => { + test('OC - Manage Tags - Edit tag departments', async ({ api, page }) => { const tag = await test.step('expect to create new tag', async () => { const { data: tag } = await createTag(api, { name: faker.string.uuid(), @@ -94,7 +94,7 @@ test.describe('OC - Manage Tags', () => { return tag; }); - await page.goto('/omnichannel'); + await page.goto('/omnichannel'); await poOmnichannelTags.sidenav.linkTags.click(); await test.step('expect to add tag departments', async () => { @@ -128,7 +128,7 @@ test.describe('OC - Manage Tags', () => { await expect(page.getByRole('option', { name: department2.data.name })).toBeHidden(); }); - await test.step('expect to delete tag', async () => { + await test.step('expect to delete tag', async () => { await poOmnichannelTags.btnDeleteByName(tag.name).click(); await expect(poOmnichannelTags.confirmDeleteModal).toBeVisible(); await poOmnichannelTags.btnConfirmDeleteModal.click(); @@ -136,4 +136,4 @@ test.describe('OC - Manage Tags', () => { await expect(page.locator('h3 >> text="No results found"')).toBeVisible(); }); }); -}); \ No newline at end of file +}); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-after-registration.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-after-registration.spec.ts index 539037219e62..70d224223744 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-after-registration.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-after-registration.spec.ts @@ -72,14 +72,14 @@ test.describe('OC - Livechat New Chat Triggers - After Registration', () => { await poLiveChat.page.goto('/livechat'); await poLiveChat.openAnyLiveChat(); await poLiveChat.sendMessage(newUser, false); - await expect(poLiveChat.txtChatMessage(triggerMessage)).toBeVisible(); - }) + await expect(poLiveChat.txtChatMessage(triggerMessage)).toBeVisible(); + }); await test.step('expect trigger message after registration to be visible after reload', async () => { await poLiveChat.page.reload(); await poLiveChat.openAnyLiveChat(); - await expect(poLiveChat.txtChatMessage(triggerMessage)).toBeVisible(); - }) + await expect(poLiveChat.txtChatMessage(triggerMessage)).toBeVisible(); + }); await test.step('expect to close room and reload', async () => { await poLiveChat.onlineAgentMessage.type('message_after_trigger'); @@ -89,13 +89,13 @@ test.describe('OC - Livechat New Chat Triggers - After Registration', () => { await expect(poLiveChat.btnNewChat).toBeVisible(); await poLiveChat.startNewChat(); - await poLiveChat.page.reload() - }) + await poLiveChat.page.reload(); + }); await test.step('expect trigger message after registration to be visible after reload on new chat', async () => { await poLiveChat.openAnyLiveChat(); await expect(poLiveChat.txtChatMessage(triggerMessage)).toBeVisible(); - }) + }); }); }); diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-units.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-units.spec.ts index 7b4b5d2611cc..9c1b5fdd5948 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-units.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-units.spec.ts @@ -222,5 +222,5 @@ test.describe('OC - Manage Units', () => { await expect(poOmnichannelUnits.contextualBar).not.toBeVisible(); }); - }) + }); }); diff --git a/apps/meteor/tests/e2e/page-objects/admin.ts b/apps/meteor/tests/e2e/page-objects/admin.ts index 791768778295..f3567652fe6e 100644 --- a/apps/meteor/tests/e2e/page-objects/admin.ts +++ b/apps/meteor/tests/e2e/page-objects/admin.ts @@ -205,7 +205,19 @@ export class Admin { return this.page.locator('input[placeholder="Room"]'); } + get inputUsers(): Locator { + return this.page.locator('input[placeholder="Users"]'); + } + + get btnAdd(): Locator { + return this.page.getByRole('button', { name: 'Add' }); + } + + get btnBack(): Locator { + return this.page.getByRole('button', { name: 'Back' }); + } + getUserRowByUsername(username: string): Locator { - return this.page.locator('tr', { hasText: username }) + return this.page.locator('tr', { hasText: username }); } } diff --git a/apps/meteor/tests/e2e/page-objects/fragments/admin-flextab-users.ts b/apps/meteor/tests/e2e/page-objects/fragments/admin-flextab-users.ts index d57d6be612c6..5b912be1fd02 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/admin-flextab-users.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/admin-flextab-users.ts @@ -53,6 +53,6 @@ export class AdminFlextabUsers { } get setupSmtpLink(): Locator { - return this.page.locator('role=link[name="Set up SMTP"]') + return this.page.locator('role=link[name="Set up SMTP"]'); } } diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts index 4f55c4f088e7..02f7dde09a85 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts @@ -359,6 +359,18 @@ export class HomeContent { return this.page.locator('role=button[name="Or talk as anonymous"]'); } + get nextSlideButton(): Locator { + return this.page.getByLabel('Next slide'); + } + + get previousSlideButton(): Locator { + return this.page.getByLabel('Previous slide'); + } + + get currentGalleryImage(): Locator { + return this.page.locator('div[class="swiper-slide swiper-slide-active"] img'); + } + findSystemMessage(text: string): Locator { return this.page.locator(`[data-qa-type="system-message-body"] >> text="${text}"`); } diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-flextab-members.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-flextab-members.ts index 7986bad4e9e6..508362429b22 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/home-flextab-members.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/home-flextab-members.ts @@ -46,7 +46,6 @@ export class HomeFlextabMembers { await this.page.getByRole('dialog').getByRole('button').first().click(); } - async setUserAsModerator(username: string) { await this.openMemberOptionMoreActions(username); await this.getMenuItemAction('Set as moderator').click(); diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-flextab-room.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-flextab-room.ts index fac98e630caa..041b37da9919 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/home-flextab-room.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/home-flextab-room.ts @@ -48,7 +48,7 @@ export class HomeFlextabRoom { } getMaxAgeLabel(maxAge = '30') { - return this.page.getByRole('dialog').getByText(`Maximum message age in days (default: ${maxAge})`) + return this.page.getByRole('dialog').getByText(`Maximum message age in days (default: ${maxAge})`); } get inputRetentionMaxAge(): Locator { diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-omnichannel-content.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-omnichannel-content.ts index 4716f6812fd7..cb2172d6fa48 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/home-omnichannel-content.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/home-omnichannel-content.ts @@ -23,11 +23,11 @@ export class HomeOmnichannelContent extends HomeContent { return this.page.locator('[data-qa-id="return-to-queue-modal"]'); } - get btnReturnToQueueConfirm():Locator { + get btnReturnToQueueConfirm(): Locator { return this.modalReturnToQueue.locator('role=button[name="Confirm"]'); } - get btnReturnToQueueCancel():Locator { + get btnReturnToQueueCancel(): Locator { return this.modalReturnToQueue.locator('role=button[name="Cancel"]'); } @@ -58,7 +58,7 @@ export class HomeOmnichannelContent extends HomeContent { get infoContactName(): Locator { return this.page.locator('[data-qa-id="contactInfo-name"]'); } - + get btnReturn(): Locator { return this.page.locator('[data-qa-id="ToolBoxAction-back"]'); } diff --git a/apps/meteor/tests/e2e/page-objects/home-channel.ts b/apps/meteor/tests/e2e/page-objects/home-channel.ts index 905a192f1f11..a5c9fa478c6c 100644 --- a/apps/meteor/tests/e2e/page-objects/home-channel.ts +++ b/apps/meteor/tests/e2e/page-objects/home-channel.ts @@ -62,7 +62,7 @@ export class HomeChannel { } get readOnlyFooter(): Locator { - return this.page.locator('footer', { hasText: 'This room is read only' }) + return this.page.locator('footer', { hasText: 'This room is read only' }); } get roomHeaderToolbar(): Locator { diff --git a/apps/meteor/tests/e2e/page-objects/home-team.ts b/apps/meteor/tests/e2e/page-objects/home-team.ts index a3b9130eb341..9225ca7a1b4d 100644 --- a/apps/meteor/tests/e2e/page-objects/home-team.ts +++ b/apps/meteor/tests/e2e/page-objects/home-team.ts @@ -32,10 +32,10 @@ export class HomeTeam { } get textPrivate(): Locator { - return this.page.locator('label', {has: this.page.getByRole('checkbox', {name: 'Private'})}); + return this.page.locator('label', { has: this.page.getByRole('checkbox', { name: 'Private' }) }); } get textReadOnly(): Locator { - return this.page.locator('label', {has: this.page.getByRole('checkbox', {name: 'Read-only'})}); + return this.page.locator('label', { has: this.page.getByRole('checkbox', { name: 'Read-only' }) }); } } diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-tags.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-tags.ts index 064877aab1c6..afb5775ba1f5 100644 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-tags.ts +++ b/apps/meteor/tests/e2e/page-objects/omnichannel-tags.ts @@ -3,67 +3,67 @@ import type { Locator } from '@playwright/test'; import { OmnichannelAdministration } from './omnichannel-administration'; export class OmnichannelTags extends OmnichannelAdministration { - get btnCreateTag(): Locator { + get btnCreateTag(): Locator { return this.page.locator('header').locator('role=button[name="Create tag"]'); } - get contextualBar(): Locator { + get contextualBar(): Locator { return this.page.locator('div[role="dialog"].rcx-vertical-bar'); } - get btnSave(): Locator { + get btnSave(): Locator { return this.contextualBar.locator('role=button[name="Save"]'); } - get btnCancel(): Locator { + get btnCancel(): Locator { return this.contextualBar.locator('role=button[name="Cancel"]'); } - get inputName(): Locator { + get inputName(): Locator { return this.page.locator('[name="name"]'); } - get inputSearch(): Locator { + get inputSearch(): Locator { return this.page.locator('[placeholder="Search"]'); } - get confirmDeleteModal(): Locator { + get confirmDeleteModal(): Locator { return this.page.locator('dialog:has(h2:has-text("Are you sure?"))'); } - get btnCancelDeleteModal(): Locator { + get btnCancelDeleteModal(): Locator { return this.confirmDeleteModal.locator('role=button[name="Cancel"]'); } - get btnConfirmDeleteModal(): Locator { + get btnConfirmDeleteModal(): Locator { return this.confirmDeleteModal.locator('role=button[name="Delete"]'); } - get btnContextualbarClose(): Locator { + get btnContextualbarClose(): Locator { return this.contextualBar.locator('button[aria-label="Close"]'); } - btnDeleteByName(name: string): Locator { + btnDeleteByName(name: string): Locator { return this.page.locator(`role=link[name="${name} Remove"] >> role=button`); } - findRowByName(name: string): Locator { + findRowByName(name: string): Locator { return this.page.locator(`tr:has-text("${name}")`); } - get inputDepartments(): Locator { - return this.page.locator('input[placeholder="Select an option"]'); + get inputDepartments(): Locator { + return this.page.locator('input[placeholder="Select an option"]'); } - - private selectOption(name: string): Locator { - return this.page.locator(`[role=option][value="${name}"]`); + + private selectOption(name: string): Locator { + return this.page.locator(`[role=option][value="${name}"]`); + } + + async search(text: string) { + await this.inputSearch.fill(text); } - - async search(text: string) { - await this.inputSearch.fill(text); - } - async selectDepartment({ name, _id }: { name: string; _id: string }) { + async selectDepartment({ name, _id }: { name: string; _id: string }) { await this.inputDepartments.click(); await this.inputDepartments.fill(name); await this.selectOption(_id).click(); diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-triggers.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-triggers.ts index 14c0ba41e989..a063952ed3ba 100644 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-triggers.ts +++ b/apps/meteor/tests/e2e/page-objects/omnichannel-triggers.ts @@ -86,7 +86,12 @@ export class OmnichannelTriggers { await this.page.locator(`li.rcx-option[data-key="${sender}"]`).click(); } - public async createTrigger(triggersName: string, triggerMessage: string, condition: "time-on-site" | "chat-opened-by-visitor" | "after-guest-registration", conditionValue?: number | string) { + public async createTrigger( + triggersName: string, + triggerMessage: string, + condition: 'time-on-site' | 'chat-opened-by-visitor' | 'after-guest-registration', + conditionValue?: number | string, + ) { await this.headingButtonNew('Create trigger').click(); await this.fillTriggerForm({ name: triggersName, diff --git a/apps/meteor/tests/e2e/presence.spec.ts b/apps/meteor/tests/e2e/presence.spec.ts new file mode 100644 index 000000000000..ad96c3cee4bf --- /dev/null +++ b/apps/meteor/tests/e2e/presence.spec.ts @@ -0,0 +1,48 @@ +import { DEFAULT_USER_CREDENTIALS, IS_EE } from './config/constants'; +import { Registration } from './page-objects'; +import { setSettingValueById } from './utils/setSettingValueById'; +import { test, expect } from './utils/test'; + +test.describe.serial('Presence', () => { + let poRegistration: Registration; + + test.beforeEach(async ({ page }) => { + poRegistration = new Registration(page); + + await page.goto('/home'); + }); + + test.beforeAll(async ({ api }) => { + await expect((await setSettingValueById(api, 'API_Use_REST_For_DDP_Calls', true)).status()).toBe(200); + }); + + test.afterAll(async ({ api }) => { + await expect((await setSettingValueById(api, 'API_Use_REST_For_DDP_Calls', true)).status()).toBe(200); + }); + + test.describe('Login using default settings', () => { + test('expect user to be online after log in', async ({ page }) => { + await poRegistration.username.type('user1'); + await poRegistration.inputPassword.type(DEFAULT_USER_CREDENTIALS.password); + await poRegistration.btnLogin.click(); + + await expect(page.getByRole('button', { name: 'User menu' }).locator('.rcx-status-bullet--online')).toBeVisible(); + }); + }); + + test.describe('Login using with "Methods by REST" disabled', () => { + test.skip(IS_EE, `Micro services don't support turning this setting off`); + + test.beforeAll(async ({ api }) => { + await expect((await setSettingValueById(api, 'API_Use_REST_For_DDP_Calls', false)).status()).toBe(200); + }); + + test('expect user to be online after log in', async ({ page }) => { + await poRegistration.username.type('user1'); + await poRegistration.inputPassword.type(DEFAULT_USER_CREDENTIALS.password); + await poRegistration.btnLogin.click(); + + await expect(page.getByRole('button', { name: 'User menu' }).locator('.rcx-status-bullet--online')).toBeVisible(); + }); + }); +}); diff --git a/apps/meteor/tests/e2e/read-receipts.spec.ts b/apps/meteor/tests/e2e/read-receipts.spec.ts index 524b79d4e919..54eb52f06fa6 100644 --- a/apps/meteor/tests/e2e/read-receipts.spec.ts +++ b/apps/meteor/tests/e2e/read-receipts.spec.ts @@ -35,7 +35,7 @@ test.describe.serial('read-receipts', () => { test.describe('read receipts enabled', async () => { test.beforeAll(async ({ api }) => { await setSettingValueById(api, 'Message_Read_Receipt_Enabled', true); - await setSettingValueById(api, 'Message_Read_Receipt_Store_Users', true); + await setSettingValueById(api, 'Message_Read_Receipt_Store_Users', true); }); test.afterAll(async ({ api }) => { @@ -48,21 +48,21 @@ test.describe.serial('read-receipts', () => { const auxContext = { page, poHomeChannel: new HomeChannel(page) }; await auxContext.poHomeChannel.sidenav.openChat(targetChannel); await auxContext.poHomeChannel.content.sendMessage('hello admin'); - + await expect(auxContext.poHomeChannel.content.lastUserMessage.getByRole('status', { name: 'Message sent' })).toBeVisible(); await auxContext.page.close(); }); - + test('should show read receipts message viewed status in the sent message', async () => { await poHomeChannel.sidenav.openChat(targetChannel); - await expect(poHomeChannel.content.lastUserMessage.getByRole('status', { name: 'Message viewed' })).toBeVisible(); + await expect(poHomeChannel.content.lastUserMessage.getByRole('status', { name: 'Message viewed' })).toBeVisible(); }); - + test('should show the reads receipt modal with the users who read the message', async ({ page }) => { await poHomeChannel.sidenav.openChat(targetChannel); await poHomeChannel.content.openLastMessageMenu(); await page.locator('role=menuitem[name="Read receipts"]').click(); - + await expect(page.getByRole('dialog').getByRole('listitem')).toHaveCount(2); }); }); diff --git a/apps/meteor/tests/e2e/register.spec.ts b/apps/meteor/tests/e2e/register.spec.ts index 1709b8414e6b..0e371aa25d97 100644 --- a/apps/meteor/tests/e2e/register.spec.ts +++ b/apps/meteor/tests/e2e/register.spec.ts @@ -129,9 +129,9 @@ test.describe.parallel('register', () => { test('should not have any accessibility violations', async ({ page, makeAxeBuilder }) => { await page.goto('/home'); await poRegistration.goToRegister.click(); - + const results = await makeAxeBuilder().analyze(); - + expect(results.violations).toEqual([]); }); }); diff --git a/apps/meteor/tests/e2e/reset-password.spec.ts b/apps/meteor/tests/e2e/reset-password.spec.ts index fc5e0b703784..fcd26eb4f355 100644 --- a/apps/meteor/tests/e2e/reset-password.spec.ts +++ b/apps/meteor/tests/e2e/reset-password.spec.ts @@ -3,33 +3,33 @@ import { setSettingValueById } from './utils/setSettingValueById'; import { test, expect } from './utils/test'; test.describe.parallel('Reset Password', () => { - let poRegistration: Registration; + let poRegistration: Registration; - test.beforeEach(async ({ api, page }) => { - poRegistration = new Registration(page); - await setSettingValueById(api, 'Accounts_RequirePasswordConfirmation', true); + test.beforeEach(async ({ api, page }) => { + poRegistration = new Registration(page); + await setSettingValueById(api, 'Accounts_RequirePasswordConfirmation', true); - await page.goto('/reset-password/someToken'); - }); + await page.goto('/reset-password/someToken'); + }); - test.afterAll(async ({ api }) => { - await setSettingValueById(api, 'Accounts_RequirePasswordConfirmation', true); - }) + test.afterAll(async ({ api }) => { + await setSettingValueById(api, 'Accounts_RequirePasswordConfirmation', true); + }); - test('should confirm password be invalid', async () => { - await poRegistration.inputPassword.fill('123456'); - await poRegistration.inputPasswordConfirm.fill('123455'); - await poRegistration.btnReset.click(); - await expect(poRegistration.inputPasswordConfirm).toBeInvalid(); - }); + test('should confirm password be invalid', async () => { + await poRegistration.inputPassword.fill('123456'); + await poRegistration.inputPasswordConfirm.fill('123455'); + await poRegistration.btnReset.click(); + await expect(poRegistration.inputPasswordConfirm).toBeInvalid(); + }); - test('should confirm password not be visible', async ({ api }) => { - await setSettingValueById(api, 'Accounts_RequirePasswordConfirmation', false); - await expect(poRegistration.inputPasswordConfirm).not.toBeVisible(); - }) + test('should confirm password not be visible', async ({ api }) => { + await setSettingValueById(api, 'Accounts_RequirePasswordConfirmation', false); + await expect(poRegistration.inputPasswordConfirm).not.toBeVisible(); + }); - test('should not have any accessibility violations', async ({ makeAxeBuilder }) => { - const results = await makeAxeBuilder().analyze(); - expect(results.violations).toEqual([]); - }) + test('should not have any accessibility violations', async ({ makeAxeBuilder }) => { + const results = await makeAxeBuilder().analyze(); + expect(results.violations).toEqual([]); + }); }); diff --git a/apps/meteor/tests/e2e/retention-policy.spec.ts b/apps/meteor/tests/e2e/retention-policy.spec.ts index 94acdc6d65f9..9c18edcf4af3 100644 --- a/apps/meteor/tests/e2e/retention-policy.spec.ts +++ b/apps/meteor/tests/e2e/retention-policy.spec.ts @@ -1,19 +1,27 @@ +import { faker } from '@faker-js/faker'; + +import { createAuxContext } from './fixtures/createAuxContext'; import { Users } from './fixtures/userStates'; import { HomeChannel } from './page-objects'; -import { createTargetChannel, createTargetPrivateChannel, setSettingValueById } from './utils'; +import { createTargetPrivateChannel, createTargetTeam, setSettingValueById } from './utils'; import { test, expect } from './utils/test'; test.use({ storageState: Users.admin.state }); test.describe.serial('retention-policy', () => { let poHomeChannel: HomeChannel; - let targetChannel: string; + const targetChannel = faker.string.uuid(); + let targetTeam: string; let targetGroup: string; test.beforeAll(async ({ api }) => { - targetChannel = await createTargetChannel(api); + const response = await api.post('/channels.create', { name: targetChannel, members: ['user1'] }); + const { channel } = await response.json(); + await api.post('/channels.addOwner', { roomId: channel._id, userId: Users.user1.data._id }); + targetGroup = await createTargetPrivateChannel(api); - }) + targetTeam = await createTargetTeam(api); + }); test.beforeEach(async ({ page }) => { poHomeChannel = new HomeChannel(page); @@ -28,6 +36,12 @@ test.describe.serial('retention-policy', () => { await expect(poHomeChannel.content.channelRetentionPolicyWarning).not.toBeVisible(); }); + test('should not show prune banner in team', async () => { + await poHomeChannel.sidenav.openChat(targetTeam); + + await expect(poHomeChannel.content.channelRetentionPolicyWarning).not.toBeVisible(); + }); + test('should not show prune section on edit channel', async () => { await poHomeChannel.sidenav.openChat(targetChannel); await poHomeChannel.tabs.btnRoomInfo.click(); @@ -37,10 +51,10 @@ test.describe.serial('retention-policy', () => { }); }); - test.describe('retention policy enabled', () => { + test.describe('retention policy enabled', () => { test.beforeAll(async ({ api }) => { await setSettingValueById(api, 'RetentionPolicy_Enabled', true); - }) + }); test.afterAll(async ({ api }) => { await setSettingValueById(api, 'RetentionPolicy_Enabled', false); await setSettingValueById(api, 'RetentionPolicy_AppliesToChannels', false); @@ -53,6 +67,9 @@ test.describe.serial('retention-policy', () => { await poHomeChannel.sidenav.openChat(targetChannel); await expect(poHomeChannel.content.channelRetentionPolicyWarning).not.toBeVisible(); + await poHomeChannel.sidenav.openChat(targetTeam); + await expect(poHomeChannel.content.channelRetentionPolicyWarning).not.toBeVisible(); + await poHomeChannel.sidenav.openChat(targetGroup); await expect(poHomeChannel.content.channelRetentionPolicyWarning).not.toBeVisible(); @@ -68,6 +85,17 @@ test.describe.serial('retention-policy', () => { await expect(poHomeChannel.tabs.room.pruneAccordion).toBeVisible(); }); + test('should not show prune section in edit channel for users without permission', async ({ browser }) => { + const { page } = await createAuxContext(browser, Users.user1); + const auxContext = { page, poHomeChannel: new HomeChannel(page) }; + await auxContext.poHomeChannel.sidenav.openChat(targetChannel); + await auxContext.poHomeChannel.tabs.btnRoomInfo.click(); + await auxContext.poHomeChannel.tabs.room.btnEdit.click(); + + await expect(poHomeChannel.tabs.room.pruneAccordion).not.toBeVisible(); + await auxContext.page.close(); + }); + test.describe('retention policy applies enabled by default', () => { test.beforeAll(async ({ api }) => { await setSettingValueById(api, 'RetentionPolicy_AppliesToChannels', true); @@ -78,7 +106,17 @@ test.describe.serial('retention-policy', () => { test('should prune old messages checkbox enabled by default in channel and show retention policy banner', async () => { await poHomeChannel.sidenav.openChat(targetChannel); await expect(poHomeChannel.content.channelRetentionPolicyWarning).toBeVisible(); - + + await poHomeChannel.tabs.btnRoomInfo.click(); + await poHomeChannel.tabs.room.btnEdit.click(); + await poHomeChannel.tabs.room.pruneAccordion.click(); + await expect(poHomeChannel.tabs.room.checkboxPruneMessages).toBeChecked(); + }); + + test('should prune old messages checkbox enabled by default in team and show retention policy banner', async () => { + await poHomeChannel.sidenav.openChat(targetTeam); + await expect(poHomeChannel.content.channelRetentionPolicyWarning).toBeVisible(); + await poHomeChannel.tabs.btnRoomInfo.click(); await poHomeChannel.tabs.room.btnEdit.click(); await poHomeChannel.tabs.room.pruneAccordion.click(); @@ -88,7 +126,7 @@ test.describe.serial('retention-policy', () => { test('should prune old messages checkbox enabled by default in group and show retention policy banner', async () => { await poHomeChannel.sidenav.openChat(targetGroup); await expect(poHomeChannel.content.channelRetentionPolicyWarning).toBeVisible(); - + await poHomeChannel.tabs.btnRoomInfo.click(); await poHomeChannel.tabs.room.btnEdit.click(); await poHomeChannel.tabs.room.pruneAccordion.click(); @@ -112,10 +150,10 @@ test.describe.serial('retention-policy', () => { await poHomeChannel.tabs.room.btnEdit.click(); await poHomeChannel.tabs.room.pruneAccordion.click(); await poHomeChannel.tabs.room.checkboxOverrideGlobalRetention.click(); - + await expect(poHomeChannel.tabs.room.getMaxAgeLabel('15')).toBeVisible(); }); - + test('should display overridden retention max age value', async () => { await poHomeChannel.sidenav.openChat(targetChannel); await poHomeChannel.tabs.btnRoomInfo.click(); @@ -125,11 +163,11 @@ test.describe.serial('retention-policy', () => { await poHomeChannel.tabs.room.inputRetentionMaxAge.fill('365'); await poHomeChannel.tabs.room.btnSave.click(); await poHomeChannel.dismissToast(); - + await poHomeChannel.tabs.btnRoomInfo.click(); await poHomeChannel.tabs.room.btnEdit.click(); await poHomeChannel.tabs.room.pruneAccordion.click(); - + await expect(poHomeChannel.tabs.room.getMaxAgeLabel('15')).toBeVisible(); await expect(poHomeChannel.tabs.room.inputRetentionMaxAge).toHaveValue('365'); }); diff --git a/apps/meteor/tests/e2e/saml.spec.ts b/apps/meteor/tests/e2e/saml.spec.ts index 8859e46e71c5..b1c1687bfa6a 100644 --- a/apps/meteor/tests/e2e/saml.spec.ts +++ b/apps/meteor/tests/e2e/saml.spec.ts @@ -2,7 +2,7 @@ import child_process from 'child_process'; import path from 'path'; import { faker } from '@faker-js/faker'; -import { Page } from '@playwright/test'; +import type { Page } from '@playwright/test'; import { v2 as compose } from 'docker-compose'; import { MongoClient } from 'mongodb'; @@ -14,7 +14,8 @@ import { createCustomRole, deleteCustomRole } from './utils/custom-role'; import { getUserInfo } from './utils/getUserInfo'; import { parseMeteorResponse } from './utils/parseMeteorResponse'; import { setSettingValueById } from './utils/setSettingValueById'; -import { test, expect, BaseTest } from './utils/test'; +import type { BaseTest } from './utils/test'; +import { test, expect } from './utils/test'; const resetTestData = async (cleanupOnly = false) => { // Reset saml users' data on mongo in the beforeAll hook to allow re-running the tests within the same playwright session @@ -196,7 +197,7 @@ test.describe('SAML', () => { }); }); - test('Allow password change for OAuth users', async ({ api }) => { + test('Allow password change for OAuth users', async ({ api }) => { await test.step("should not send password reset mail if 'Allow Password Change for OAuth Users' setting is disabled", async () => { expect((await setSettingValueById(api, 'Accounts_AllowPasswordChangeForOAuthUsers', false)).status()).toBe(200); diff --git a/apps/meteor/tests/e2e/search-discussion.spec.ts b/apps/meteor/tests/e2e/search-discussion.spec.ts index e14813bc2dc3..0d645432d777 100644 --- a/apps/meteor/tests/e2e/search-discussion.spec.ts +++ b/apps/meteor/tests/e2e/search-discussion.spec.ts @@ -1,4 +1,4 @@ -import { Page } from '@playwright/test'; +import type { Page } from '@playwright/test'; import { Users } from './fixtures/userStates'; import { HomeChannel } from './page-objects'; @@ -33,7 +33,7 @@ test.describe.serial('search-discussion', () => { await poHomeChannel.sidenav.inputSearch.type(discussionName); const targetSearchItem = page.locator('role=listbox').getByText(discussionName).first(); await expect(targetSearchItem).toBeVisible(); - } + }; test('expect search discussion to show fname when UI_Allow_room_names_with_special_chars=true', async ({ page, api }) => { await setSettingValueById(api, 'UI_Allow_room_names_with_special_chars', true); diff --git a/apps/meteor/tests/e2e/sidebar-administration-menu.spec.ts b/apps/meteor/tests/e2e/sidebar-administration-menu.spec.ts index c5b1f68b4cd4..e72149242e90 100644 --- a/apps/meteor/tests/e2e/sidebar-administration-menu.spec.ts +++ b/apps/meteor/tests/e2e/sidebar-administration-menu.spec.ts @@ -18,17 +18,17 @@ test.describe.serial('sidebar-administration-menu', () => { test('should open workspace page', async ({ page }) => { test.skip(!IS_EE, 'Enterprise only'); await poHomeDiscussion.sidenav.openAdministrationByLabel('Workspace'); - + await expect(page).toHaveURL('admin/info'); }); - + test('should open omnichannel page', async ({ page }) => { await poHomeDiscussion.sidenav.openAdministrationByLabel('Omnichannel'); - + await expect(page).toHaveURL('omnichannel/current'); }); }); - + test.describe('regular user', () => { test.use({ storageState: Users.user1.state }); diff --git a/apps/meteor/tests/e2e/sidebar.spec.ts b/apps/meteor/tests/e2e/sidebar.spec.ts index dbe14f0733bf..a172fe72d1be 100644 --- a/apps/meteor/tests/e2e/sidebar.spec.ts +++ b/apps/meteor/tests/e2e/sidebar.spec.ts @@ -13,23 +13,23 @@ test.describe.serial('sidebar', () => { await page.goto('/home'); }); - test('should navigate on sidebar toolbar using arrow keys', async ({ page }) => { - await poHomeDiscussion.sidenav.userProfileMenu.focus(); - await page.keyboard.press('Tab'); - await page.keyboard.press('ArrowRight'); - - await expect(poHomeDiscussion.sidenav.sidebarToolbar.getByRole('button', { name: 'Search' })).toBeFocused(); - }); - - test('should navigate on sidebar items using arrow keys and restore focus', async ({ page }) => { - // focus should be on the next item - await poHomeDiscussion.sidenav.sidebarChannelsList.getByRole('link').first().focus(); - await page.keyboard.press('ArrowDown'); - await expect(poHomeDiscussion.sidenav.sidebarChannelsList.getByRole('link').first()).not.toBeFocused(); - - // shouldn't focus the first item - await page.keyboard.press('Shift+Tab'); - await page.keyboard.press('Tab'); - await expect(poHomeDiscussion.sidenav.sidebarChannelsList.getByRole('link').first()).not.toBeFocused(); - }); + test('should navigate on sidebar toolbar using arrow keys', async ({ page }) => { + await poHomeDiscussion.sidenav.userProfileMenu.focus(); + await page.keyboard.press('Tab'); + await page.keyboard.press('ArrowRight'); + + await expect(poHomeDiscussion.sidenav.sidebarToolbar.getByRole('button', { name: 'Search' })).toBeFocused(); + }); + + test('should navigate on sidebar items using arrow keys and restore focus', async ({ page }) => { + // focus should be on the next item + await poHomeDiscussion.sidenav.sidebarChannelsList.getByRole('link').first().focus(); + await page.keyboard.press('ArrowDown'); + await expect(poHomeDiscussion.sidenav.sidebarChannelsList.getByRole('link').first()).not.toBeFocused(); + + // shouldn't focus the first item + await page.keyboard.press('Shift+Tab'); + await page.keyboard.press('Tab'); + await expect(poHomeDiscussion.sidenav.sidebarChannelsList.getByRole('link').first()).not.toBeFocused(); + }); }); diff --git a/apps/meteor/tests/e2e/threads.spec.ts b/apps/meteor/tests/e2e/threads.spec.ts index a7fa19422ff5..16198c15a942 100644 --- a/apps/meteor/tests/e2e/threads.spec.ts +++ b/apps/meteor/tests/e2e/threads.spec.ts @@ -142,7 +142,7 @@ test.describe.serial('Threads', () => { await poHomeChannel.content.openLastThreadMessageMenu(); await page.locator('role=menuitem[name="Copy text"]').click(); - const clipboardText = await page.evaluate("navigator.clipboard.readText()"); + const clipboardText = await page.evaluate('navigator.clipboard.readText()'); expect(clipboardText).toBe('this is a message for reply'); }); @@ -151,7 +151,7 @@ test.describe.serial('Threads', () => { await poHomeChannel.content.openLastThreadMessageMenu(); await page.locator('role=menuitem[name="Copy link"]').click(); - const clipboardText = await page.evaluate("navigator.clipboard.readText()"); + const clipboardText = await page.evaluate('navigator.clipboard.readText()'); expect(clipboardText).toContain('http'); }); diff --git a/apps/meteor/tests/e2e/utils/create-target-channel.ts b/apps/meteor/tests/e2e/utils/create-target-channel.ts index d5b10aaa9e1a..8f7a25aa9718 100644 --- a/apps/meteor/tests/e2e/utils/create-target-channel.ts +++ b/apps/meteor/tests/e2e/utils/create-target-channel.ts @@ -48,7 +48,7 @@ export async function createTargetDiscussion(api: BaseTest['api']): Promise { await api.post('/users.setStatus', { diff --git a/apps/meteor/tests/e2e/utils/omnichannel/departments.ts b/apps/meteor/tests/e2e/utils/omnichannel/departments.ts index 455410808720..fb7d8cd14ec3 100644 --- a/apps/meteor/tests/e2e/utils/omnichannel/departments.ts +++ b/apps/meteor/tests/e2e/utils/omnichannel/departments.ts @@ -1,9 +1,9 @@ import { faker } from '@faker-js/faker'; -import { ILivechatDepartment } from '@rocket.chat/core-typings'; +import type { ILivechatDepartment } from '@rocket.chat/core-typings'; -import { BaseTest } from '../test'; +import type { BaseTest } from '../test'; -type CreateDepartmentParams = { +type CreateDepartmentParams = { name?: string; enabled?: boolean; description?: string; @@ -13,29 +13,32 @@ type CreateDepartmentParams = { email?: string; chatClosingTags?: string[]; offlineMessageChannelName?: string; - abandonedRoomsCloseCustomMessage?: string, + abandonedRoomsCloseCustomMessage?: string; waitingQueueMessage?: string; departmentsAllowedToForward?: string[]; fallbackForwardDepartment?: string; maxNumberSimultaneousChat?: number; - }; +}; -export const createDepartment = async (api: BaseTest['api'], { - name = '', - enabled = true, - description = '', - showOnRegistration = false, - showOnOfflineForm = false, - requestTagBeforeClosingChat = false, - email = '', - chatClosingTags = [], - offlineMessageChannelName = '', - abandonedRoomsCloseCustomMessage = '', - waitingQueueMessage = '', - departmentsAllowedToForward = [], - fallbackForwardDepartment = '', - maxNumberSimultaneousChat -}: CreateDepartmentParams = {}) => { +export const createDepartment = async ( + api: BaseTest['api'], + { + name = '', + enabled = true, + description = '', + showOnRegistration = false, + showOnOfflineForm = false, + requestTagBeforeClosingChat = false, + email = '', + chatClosingTags = [], + offlineMessageChannelName = '', + abandonedRoomsCloseCustomMessage = '', + waitingQueueMessage = '', + departmentsAllowedToForward = [], + fallbackForwardDepartment = '', + maxNumberSimultaneousChat, + }: CreateDepartmentParams = {}, +) => { const response = await api.post('/livechat/department', { department: { name: name || faker.string.uuid(), diff --git a/apps/meteor/tests/e2e/utils/omnichannel/managers.ts b/apps/meteor/tests/e2e/utils/omnichannel/managers.ts index 3fb5f04dcc96..f32ecad45900 100644 --- a/apps/meteor/tests/e2e/utils/omnichannel/managers.ts +++ b/apps/meteor/tests/e2e/utils/omnichannel/managers.ts @@ -1,4 +1,4 @@ -import { BaseTest } from '../test'; +import type { BaseTest } from '../test'; export const createManager = async (api: BaseTest['api'], username: string) => { const response = await api.post('/livechat/users/manager', { diff --git a/apps/meteor/tests/e2e/utils/omnichannel/monitors.ts b/apps/meteor/tests/e2e/utils/omnichannel/monitors.ts index f92ff9244ec5..5c14b4f607a9 100644 --- a/apps/meteor/tests/e2e/utils/omnichannel/monitors.ts +++ b/apps/meteor/tests/e2e/utils/omnichannel/monitors.ts @@ -1,5 +1,5 @@ import { parseMeteorResponse } from '../parseMeteorResponse'; -import { BaseTest } from '../test'; +import type { BaseTest } from '../test'; const removeMonitor = async (api: BaseTest['api'], id: string) => api.post('/method.call/livechat:removeMonitor', { diff --git a/apps/meteor/tests/e2e/utils/omnichannel/rooms.ts b/apps/meteor/tests/e2e/utils/omnichannel/rooms.ts index c07c5376130f..feec31e2a819 100644 --- a/apps/meteor/tests/e2e/utils/omnichannel/rooms.ts +++ b/apps/meteor/tests/e2e/utils/omnichannel/rooms.ts @@ -1,6 +1,6 @@ import { faker } from '@faker-js/faker'; -import { BaseTest } from '../test'; +import type { BaseTest } from '../test'; type UpdateRoomParams = { roomId: string; visitorId: string; tags: string[] }; diff --git a/apps/meteor/tests/e2e/utils/omnichannel/tags.ts b/apps/meteor/tests/e2e/utils/omnichannel/tags.ts index 169f4825bd75..ba2a6b43e4d2 100644 --- a/apps/meteor/tests/e2e/utils/omnichannel/tags.ts +++ b/apps/meteor/tests/e2e/utils/omnichannel/tags.ts @@ -1,7 +1,7 @@ -import { ILivechatTag } from '@rocket.chat/core-typings'; +import type { ILivechatTag } from '@rocket.chat/core-typings'; import { parseMeteorResponse } from '../parseMeteorResponse'; -import { BaseTest } from '../test'; +import type { BaseTest } from '../test'; type CreateTagParams = { id?: string | null; @@ -15,23 +15,21 @@ const removeTag = async (api: BaseTest['api'], id: string) => message: JSON.stringify({ msg: 'method', id: '33', method: 'livechat:removeTag', params: [id] }), }); -export const createTag = async ( - api: BaseTest['api'], - { id = null, name, description = '', departments = [] }: CreateTagParams = {}, - ) => { - const response = await api.post('/method.call/livechat:saveTag', { - message: JSON.stringify({ - msg: 'method', - id: '33', - method: 'livechat:saveTag', - params: [id, { name, description }, departments]}) - }); +export const createTag = async (api: BaseTest['api'], { id = null, name, description = '', departments = [] }: CreateTagParams = {}) => { + const response = await api.post('/method.call/livechat:saveTag', { + message: JSON.stringify({ + msg: 'method', + id: '33', + method: 'livechat:saveTag', + params: [id, { name, description }, departments], + }), + }); - const tag = await parseMeteorResponse(response); + const tag = await parseMeteorResponse(response); - return { - response, - data: tag, - delete: async () => removeTag(api, tag?._id), - }; + return { + response, + data: tag, + delete: async () => removeTag(api, tag?._id), + }; }; diff --git a/apps/meteor/tests/e2e/utils/omnichannel/units.ts b/apps/meteor/tests/e2e/utils/omnichannel/units.ts index bbc37ed12df8..596c074191ed 100644 --- a/apps/meteor/tests/e2e/utils/omnichannel/units.ts +++ b/apps/meteor/tests/e2e/utils/omnichannel/units.ts @@ -1,8 +1,8 @@ import { faker } from '@faker-js/faker'; -import { IOmnichannelBusinessUnit } from '@rocket.chat/core-typings'; +import type { IOmnichannelBusinessUnit } from '@rocket.chat/core-typings'; import { parseMeteorResponse } from '../parseMeteorResponse'; -import { BaseTest } from '../test'; +import type { BaseTest } from '../test'; type CreateUnitParams = { id?: string | null; diff --git a/apps/meteor/tests/e2e/utils/parseMeteorResponse.ts b/apps/meteor/tests/e2e/utils/parseMeteorResponse.ts index edecd3ea4ce3..24adc1574b28 100644 --- a/apps/meteor/tests/e2e/utils/parseMeteorResponse.ts +++ b/apps/meteor/tests/e2e/utils/parseMeteorResponse.ts @@ -1,5 +1,5 @@ -import { APIResponse } from '@playwright/test'; -import { Serialized } from '@rocket.chat/core-typings'; +import type { APIResponse } from '@playwright/test'; +import type { Serialized } from '@rocket.chat/core-typings'; export const parseMeteorResponse = async (response: APIResponse): Promise> => { const { message, success } = await response.json(); diff --git a/apps/meteor/tests/e2e/utils/setUserPreferences.ts b/apps/meteor/tests/e2e/utils/setUserPreferences.ts index fcb1f930d21a..2e55f22dd9e6 100644 --- a/apps/meteor/tests/e2e/utils/setUserPreferences.ts +++ b/apps/meteor/tests/e2e/utils/setUserPreferences.ts @@ -1,5 +1,5 @@ import type { APIResponse } from '@playwright/test'; -import { UsersSetPreferencesParamsPOST } from '@rocket.chat/rest-typings'; +import type { UsersSetPreferencesParamsPOST } from '@rocket.chat/rest-typings'; import type { BaseTest } from './test'; diff --git a/apps/meteor/tests/end-to-end/api/01-users.js b/apps/meteor/tests/end-to-end/api/01-users.js index c63422b071b6..b1d9a594996b 100644 --- a/apps/meteor/tests/end-to-end/api/01-users.js +++ b/apps/meteor/tests/end-to-end/api/01-users.js @@ -23,7 +23,7 @@ import { } from '../../data/rooms.helper'; import { createTeam, deleteTeam } from '../../data/teams.helper'; import { adminEmail, preferences, password, adminUsername } from '../../data/user'; -import { createUser, login, deleteUser, getUserStatus, getUserByUsername, registerUser } from '../../data/users.helper.js'; +import { createUser, login, deleteUser, getUserStatus, getUserByUsername, registerUser, updateUserInDb } from '../../data/users.helper.js'; const targetUser = {}; @@ -1653,6 +1653,34 @@ describe('[Users]', function () { }); }); + it('should delete requirePasswordChangeReason when requirePasswordChange is set to false', async () => { + const user = await createUser({ + requirePasswordChange: true, + }); + + await updateUserInDb(user._id, { requirePasswordChangeReason: 'any_data' }); + + await request + .post(api('users.update')) + .set(credentials) + .send({ + userId: user._id, + data: { + requirePasswordChange: false, + }, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('user'); + expect(res.body.user).to.have.property('requirePasswordChange', false); + expect(res.body.user).to.not.have.property('requirePasswordChangeReason'); + }); + + await deleteUser(user); + }); + function failUpdateUser(name) { it(`should not update an user if the new username is the reserved word ${name}`, (done) => { request diff --git a/apps/meteor/tests/mocks/data/marketplace.ts b/apps/meteor/tests/mocks/data/marketplace.ts new file mode 100644 index 000000000000..cb8c5d67ad10 --- /dev/null +++ b/apps/meteor/tests/mocks/data/marketplace.ts @@ -0,0 +1,116 @@ +import { faker } from '@faker-js/faker'; +import type { AppStatus } from '@rocket.chat/apps'; +import { type App, type AppSubscriptionInfo, AppSubscriptionStatus } from '@rocket.chat/core-typings'; + +import { createFakeApp } from '../data'; + +// Zero-value of the subscriptionInfo field on marketplace-api +// returned by the API when the app has no value assigned to the field +const subscriptionInfoZero = (): AppSubscriptionInfo => ({ + typeOf: '', + status: '' as AppSubscriptionStatus, // real value that is sent currently, enum should be updated + statusFromBilling: false, + isSeatBased: false, + seats: 0, + maxSeats: 0, + license: { + license: '', + version: 0, + expireDate: '0001-01-01T00:00:00Z', + }, + startDate: '0001-01-01T00:00:00Z', + periodEnd: '0001-01-01T00:00:00Z', + endDate: '0001-01-01T00:00:00Z', + // externallyManaged: false, // TODO add to typings + isSubscribedViaBundle: false, +}); + +/* + * Creates a fake record of an app that has been bought from the Marketplace + */ +export function createFakeAppBought(partial: Partial = {}): App { + const app = createFakeApp({ + isPurchased: true, + isSubscribed: false, + purchaseType: 'buy', + // isUsageBased: false, // TODO add to typings + subscriptionInfo: subscriptionInfoZero(), + ...partial, + }); + + return app; +} + +export function createFakeAppSubscribed(partial: Partial = {}): App { + const app = createFakeApp({ + isSubscribed: true, + isPurchased: false, + purchaseType: 'subscription', + subscriptionInfo: { + typeOf: 'app', + status: AppSubscriptionStatus.Active, + statusFromBilling: faker.datatype.boolean(), + isSeatBased: faker.datatype.boolean(), + seats: faker.number.int({ min: 0, max: 50 }), + maxSeats: faker.number.int({ min: 50, max: 100 }), + license: { + license: faker.lorem.word(), + version: faker.number.int({ min: 0, max: 3 }), + expireDate: faker.date.future().toISOString(), + }, + startDate: faker.date.past().toISOString(), + periodEnd: faker.date.future().toISOString(), + endDate: faker.date.future().toISOString(), + isSubscribedViaBundle: faker.datatype.boolean(), + }, + ...partial, + }); + + return app; +} + +export function createFakeAppInstalledMarketplace(partial: Partial = {}): App { + const app = createFakeAppBought({ + installed: true, + private: false, + status: 'manually_enabled' as AppStatus.MANUALLY_ENABLED, + licenseValidation: { + errors: {}, + warnings: {}, + }, + ...partial, + }); + + return app; +} + +export function createFakeAppPrivate(partial: Partial = {}): App { + const app = createFakeApp({ + installed: true, + private: true, + status: 'manually_enabled' as AppStatus.MANUALLY_ENABLED, + // Fields from marketplace + appRequestStats: undefined, + shortDescription: undefined, + price: undefined, + pricingPlans: undefined, + purchaseType: undefined, + isPurchased: undefined, + isSubscribed: undefined, + tosLink: undefined, + bundledIn: undefined, + privacyLink: undefined, + privacyPolicySummary: undefined, + documentationUrl: undefined, + detailedChangelog: undefined, + detailedDescription: undefined, + categories: undefined, + versionIncompatible: undefined, + marketplaceVersion: undefined, + latest: undefined, + subscriptionInfo: undefined, + ...partial, + }); + + return app; +} diff --git a/ee/apps/account-service/CHANGELOG.md b/ee/apps/account-service/CHANGELOG.md index 666eda95454d..39eaf3f73387 100644 --- a/ee/apps/account-service/CHANGELOG.md +++ b/ee/apps/account-service/CHANGELOG.md @@ -1,5 +1,57 @@ # @rocket.chat/account-service +## 0.3.14 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, f83bd56cc5, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/core-services@0.3.15 + - @rocket.chat/rest-typings@6.9.0 + - @rocket.chat/model-typings@0.4.1 + - @rocket.chat/models@0.0.39 +
+ +## 0.3.14-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/rest-typings@6.9.0-rc.2 + - @rocket.chat/core-services@0.3.15-rc.2 + - @rocket.chat/model-typings@0.4.1-rc.2 + - @rocket.chat/models@0.0.39-rc.2 +
+ +## 0.3.14-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/rest-typings@6.9.0-rc.1 + - @rocket.chat/core-services@0.3.15-rc.1 + - @rocket.chat/model-typings@0.4.1-rc.1 + - @rocket.chat/models@0.0.39-rc.1 +
+ +## 0.3.14-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, f83bd56cc5, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/core-services@0.3.15-rc.0 + - @rocket.chat/rest-typings@6.9.0-rc.0 + - @rocket.chat/model-typings@0.4.1-rc.0 + - @rocket.chat/models@0.0.39-rc.0 +
+ ## 0.3.13 ### Patch Changes diff --git a/ee/apps/account-service/package.json b/ee/apps/account-service/package.json index 0ccbbce820f2..6abc5aa783bc 100644 --- a/ee/apps/account-service/package.json +++ b/ee/apps/account-service/package.json @@ -1,7 +1,7 @@ { "name": "@rocket.chat/account-service", "private": true, - "version": "0.3.13", + "version": "0.3.14", "description": "Rocket.Chat Account service", "scripts": { "build": "tsc -p tsconfig.json", diff --git a/ee/apps/authorization-service/CHANGELOG.md b/ee/apps/authorization-service/CHANGELOG.md index 80940bcb4ff4..fd73dae11270 100644 --- a/ee/apps/authorization-service/CHANGELOG.md +++ b/ee/apps/authorization-service/CHANGELOG.md @@ -1,5 +1,57 @@ # @rocket.chat/authorization-service +## 0.3.15 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, f83bd56cc5, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/core-services@0.3.15 + - @rocket.chat/rest-typings@6.9.0 + - @rocket.chat/model-typings@0.4.1 + - @rocket.chat/models@0.0.39 +
+ +## 0.3.15-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/rest-typings@6.9.0-rc.2 + - @rocket.chat/core-services@0.3.15-rc.2 + - @rocket.chat/model-typings@0.4.1-rc.2 + - @rocket.chat/models@0.0.39-rc.2 +
+ +## 0.3.15-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/rest-typings@6.9.0-rc.1 + - @rocket.chat/core-services@0.3.15-rc.1 + - @rocket.chat/model-typings@0.4.1-rc.1 + - @rocket.chat/models@0.0.39-rc.1 +
+ +## 0.3.15-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, f83bd56cc5, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/core-services@0.3.15-rc.0 + - @rocket.chat/rest-typings@6.9.0-rc.0 + - @rocket.chat/model-typings@0.4.1-rc.0 + - @rocket.chat/models@0.0.39-rc.0 +
+ ## 0.3.14 ### Patch Changes diff --git a/ee/apps/authorization-service/package.json b/ee/apps/authorization-service/package.json index 13546b16d3b3..61de30257359 100644 --- a/ee/apps/authorization-service/package.json +++ b/ee/apps/authorization-service/package.json @@ -1,7 +1,7 @@ { "name": "@rocket.chat/authorization-service", "private": true, - "version": "0.3.14", + "version": "0.3.15", "description": "Rocket.Chat Authorization service", "scripts": { "build": "tsc -p tsconfig.json", diff --git a/ee/apps/ddp-streamer/CHANGELOG.md b/ee/apps/ddp-streamer/CHANGELOG.md index 5376a1baad58..75409b275c32 100644 --- a/ee/apps/ddp-streamer/CHANGELOG.md +++ b/ee/apps/ddp-streamer/CHANGELOG.md @@ -1,5 +1,65 @@ # @rocket.chat/ddp-streamer +## 0.2.14 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, f83bd56cc5, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/core-services@0.3.15 + - @rocket.chat/rest-typings@6.9.0 + - @rocket.chat/model-typings@0.4.1 + - @rocket.chat/ui-contexts@7.0.0 + - @rocket.chat/models@0.0.39 + - @rocket.chat/instance-status@0.0.39 +
+ +## 0.2.14-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/rest-typings@6.9.0-rc.2 + - @rocket.chat/core-services@0.3.15-rc.2 + - @rocket.chat/model-typings@0.4.1-rc.2 + - @rocket.chat/ui-contexts@7.0.0-rc.2 + - @rocket.chat/models@0.0.39-rc.2 + - @rocket.chat/instance-status@0.0.39-rc.2 +
+ +## 0.2.14-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/rest-typings@6.9.0-rc.1 + - @rocket.chat/core-services@0.3.15-rc.1 + - @rocket.chat/model-typings@0.4.1-rc.1 + - @rocket.chat/ui-contexts@7.0.0-rc.1 + - @rocket.chat/models@0.0.39-rc.1 + - @rocket.chat/instance-status@0.0.39-rc.1 +
+ +## 0.2.14-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, f83bd56cc5, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/core-services@0.3.15-rc.0 + - @rocket.chat/rest-typings@6.9.0-rc.0 + - @rocket.chat/model-typings@0.4.1-rc.0 + - @rocket.chat/ui-contexts@7.0.0-rc.0 + - @rocket.chat/models@0.0.39-rc.0 + - @rocket.chat/instance-status@0.0.39-rc.0 +
+ ## 0.2.13 ### Patch Changes diff --git a/ee/apps/ddp-streamer/package.json b/ee/apps/ddp-streamer/package.json index 8cc41e5b8e3c..c1dd482d2e75 100644 --- a/ee/apps/ddp-streamer/package.json +++ b/ee/apps/ddp-streamer/package.json @@ -1,7 +1,7 @@ { "name": "@rocket.chat/ddp-streamer", "private": true, - "version": "0.2.13", + "version": "0.2.14", "description": "Rocket.Chat DDP-Streamer service", "scripts": { "build": "tsc -p tsconfig.json", diff --git a/ee/apps/omnichannel-transcript/CHANGELOG.md b/ee/apps/omnichannel-transcript/CHANGELOG.md index a2530269d793..1da1ca34fa23 100644 --- a/ee/apps/omnichannel-transcript/CHANGELOG.md +++ b/ee/apps/omnichannel-transcript/CHANGELOG.md @@ -1,5 +1,61 @@ # @rocket.chat/omnichannel-transcript +## 0.3.15 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/core-services@0.3.15 + - @rocket.chat/omnichannel-services@0.1.15 + - @rocket.chat/pdf-worker@0.0.39 + - @rocket.chat/model-typings@0.4.1 + - @rocket.chat/models@0.0.39 +
+ +## 0.3.15-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/omnichannel-services@0.1.15-rc.2 + - @rocket.chat/pdf-worker@0.0.39-rc.2 + - @rocket.chat/core-services@0.3.15-rc.2 + - @rocket.chat/model-typings@0.4.1-rc.2 + - @rocket.chat/models@0.0.39-rc.2 +
+ +## 0.3.15-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/omnichannel-services@0.1.15-rc.1 + - @rocket.chat/pdf-worker@0.0.39-rc.1 + - @rocket.chat/core-services@0.3.15-rc.1 + - @rocket.chat/model-typings@0.4.1-rc.1 + - @rocket.chat/models@0.0.39-rc.1 +
+ +## 0.3.15-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/core-services@0.3.15-rc.0 + - @rocket.chat/omnichannel-services@0.1.15-rc.0 + - @rocket.chat/pdf-worker@0.0.39-rc.0 + - @rocket.chat/model-typings@0.4.1-rc.0 + - @rocket.chat/models@0.0.39-rc.0 +
+ ## 0.3.14 ### Patch Changes diff --git a/ee/apps/omnichannel-transcript/package.json b/ee/apps/omnichannel-transcript/package.json index 5a8da65d51a4..9705a4ca2e2c 100644 --- a/ee/apps/omnichannel-transcript/package.json +++ b/ee/apps/omnichannel-transcript/package.json @@ -1,7 +1,7 @@ { "name": "@rocket.chat/omnichannel-transcript", "private": true, - "version": "0.3.14", + "version": "0.3.15", "description": "Rocket.Chat service", "scripts": { "build": "tsc -p tsconfig.json", diff --git a/ee/apps/presence-service/CHANGELOG.md b/ee/apps/presence-service/CHANGELOG.md index 3bd7b9952832..a90edcd821af 100644 --- a/ee/apps/presence-service/CHANGELOG.md +++ b/ee/apps/presence-service/CHANGELOG.md @@ -1,5 +1,57 @@ # @rocket.chat/presence-service +## 0.3.15 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/core-services@0.3.15 + - @rocket.chat/presence@0.1.15 + - @rocket.chat/model-typings@0.4.1 + - @rocket.chat/models@0.0.39 +
+ +## 0.3.15-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/presence@0.1.15-rc.2 + - @rocket.chat/core-services@0.3.15-rc.2 + - @rocket.chat/model-typings@0.4.1-rc.2 + - @rocket.chat/models@0.0.39-rc.2 +
+ +## 0.3.15-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/presence@0.1.15-rc.1 + - @rocket.chat/core-services@0.3.15-rc.1 + - @rocket.chat/model-typings@0.4.1-rc.1 + - @rocket.chat/models@0.0.39-rc.1 +
+ +## 0.3.15-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/core-services@0.3.15-rc.0 + - @rocket.chat/presence@0.1.15-rc.0 + - @rocket.chat/model-typings@0.4.1-rc.0 + - @rocket.chat/models@0.0.39-rc.0 +
+ ## 0.3.14 ### Patch Changes diff --git a/ee/apps/presence-service/package.json b/ee/apps/presence-service/package.json index 10b47541cb82..129eae6f6f14 100644 --- a/ee/apps/presence-service/package.json +++ b/ee/apps/presence-service/package.json @@ -1,7 +1,7 @@ { "name": "@rocket.chat/presence-service", "private": true, - "version": "0.3.14", + "version": "0.3.15", "description": "Rocket.Chat Presence service", "scripts": { "build": "tsc -p tsconfig.json", diff --git a/ee/apps/queue-worker/CHANGELOG.md b/ee/apps/queue-worker/CHANGELOG.md index 2834b6301181..57508316acbf 100644 --- a/ee/apps/queue-worker/CHANGELOG.md +++ b/ee/apps/queue-worker/CHANGELOG.md @@ -1,5 +1,57 @@ # @rocket.chat/queue-worker +## 0.3.15 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/core-services@0.3.15 + - @rocket.chat/omnichannel-services@0.1.15 + - @rocket.chat/model-typings@0.4.1 + - @rocket.chat/models@0.0.39 +
+ +## 0.3.15-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/omnichannel-services@0.1.15-rc.2 + - @rocket.chat/core-services@0.3.15-rc.2 + - @rocket.chat/model-typings@0.4.1-rc.2 + - @rocket.chat/models@0.0.39-rc.2 +
+ +## 0.3.15-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/omnichannel-services@0.1.15-rc.1 + - @rocket.chat/core-services@0.3.15-rc.1 + - @rocket.chat/model-typings@0.4.1-rc.1 + - @rocket.chat/models@0.0.39-rc.1 +
+ +## 0.3.15-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/core-services@0.3.15-rc.0 + - @rocket.chat/omnichannel-services@0.1.15-rc.0 + - @rocket.chat/model-typings@0.4.1-rc.0 + - @rocket.chat/models@0.0.39-rc.0 +
+ ## 0.3.14 ### Patch Changes diff --git a/ee/apps/queue-worker/package.json b/ee/apps/queue-worker/package.json index 4864e4a34c9b..d2f07cc5e312 100644 --- a/ee/apps/queue-worker/package.json +++ b/ee/apps/queue-worker/package.json @@ -1,7 +1,7 @@ { "name": "@rocket.chat/queue-worker", "private": true, - "version": "0.3.14", + "version": "0.3.15", "description": "Rocket.Chat service", "scripts": { "build": "tsc -p tsconfig.json", diff --git a/ee/apps/stream-hub-service/CHANGELOG.md b/ee/apps/stream-hub-service/CHANGELOG.md index e6a8f79aedd8..089b9c8fbd3c 100644 --- a/ee/apps/stream-hub-service/CHANGELOG.md +++ b/ee/apps/stream-hub-service/CHANGELOG.md @@ -1,5 +1,53 @@ # @rocket.chat/stream-hub-service +## 0.3.15 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/core-services@0.3.15 + - @rocket.chat/model-typings@0.4.1 + - @rocket.chat/models@0.0.39 +
+ +## 0.3.15-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/core-services@0.3.15-rc.2 + - @rocket.chat/model-typings@0.4.1-rc.2 + - @rocket.chat/models@0.0.39-rc.2 +
+ +## 0.3.15-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/core-services@0.3.15-rc.1 + - @rocket.chat/model-typings@0.4.1-rc.1 + - @rocket.chat/models@0.0.39-rc.1 +
+ +## 0.3.15-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/core-services@0.3.15-rc.0 + - @rocket.chat/model-typings@0.4.1-rc.0 + - @rocket.chat/models@0.0.39-rc.0 +
+ ## 0.3.14 ### Patch Changes diff --git a/ee/apps/stream-hub-service/package.json b/ee/apps/stream-hub-service/package.json index 76076b4d3030..a2ac2464c0aa 100644 --- a/ee/apps/stream-hub-service/package.json +++ b/ee/apps/stream-hub-service/package.json @@ -1,7 +1,7 @@ { "name": "@rocket.chat/stream-hub-service", "private": true, - "version": "0.3.14", + "version": "0.3.15", "description": "Rocket.Chat Stream Hub service", "scripts": { "build": "tsc -p tsconfig.json", diff --git a/ee/packages/api-client/CHANGELOG.md b/ee/packages/api-client/CHANGELOG.md index 28df5106b12f..62278200a94d 100644 --- a/ee/packages/api-client/CHANGELOG.md +++ b/ee/packages/api-client/CHANGELOG.md @@ -1,5 +1,45 @@ # @rocket.chat/api-client +## 0.1.33 + +### Patch Changes + +-
Updated dependencies [ff4e396416, f83bd56cc5, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/rest-typings@6.9.0 +
+ +## 0.1.33-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/rest-typings@6.9.0-rc.2 +
+ +## 0.1.33-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/rest-typings@6.9.0-rc.1 +
+ +## 0.1.33-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, f83bd56cc5, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/rest-typings@6.9.0-rc.0 +
+ ## 0.1.32 ### Patch Changes diff --git a/ee/packages/api-client/package.json b/ee/packages/api-client/package.json index 096eec4ee113..f4b22774490b 100644 --- a/ee/packages/api-client/package.json +++ b/ee/packages/api-client/package.json @@ -1,7 +1,6 @@ { "name": "@rocket.chat/api-client", - "private": true, - "version": "0.1.32", + "version": "0.1.33", "devDependencies": { "@swc/core": "^1.3.95", "@swc/jest": "^0.2.29", diff --git a/ee/packages/ddp-client/CHANGELOG.md b/ee/packages/ddp-client/CHANGELOG.md index 80aada44fcab..8c64d0836416 100644 --- a/ee/packages/ddp-client/CHANGELOG.md +++ b/ee/packages/ddp-client/CHANGELOG.md @@ -1,5 +1,45 @@ # @rocket.chat/ddp-client +## 0.2.24 + +### Patch Changes + +-
Updated dependencies [f83bd56cc5]: + + - @rocket.chat/rest-typings@6.9.0 + - @rocket.chat/api-client@0.1.33 +
+ +## 0.2.24-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/rest-typings@6.9.0-rc.2 + - @rocket.chat/api-client@0.1.33-rc.2 +
+ +## 0.2.24-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/rest-typings@6.9.0-rc.1 + - @rocket.chat/api-client@0.1.33-rc.1 +
+ +## 0.2.24-rc.0 + +### Patch Changes + +-
Updated dependencies [f83bd56cc5]: + + - @rocket.chat/rest-typings@6.9.0-rc.0 + - @rocket.chat/api-client@0.1.33-rc.0 +
+ ## 0.2.23 ### Patch Changes diff --git a/ee/packages/ddp-client/package.json b/ee/packages/ddp-client/package.json index daf3a22c5da6..cbf3bd20c52b 100644 --- a/ee/packages/ddp-client/package.json +++ b/ee/packages/ddp-client/package.json @@ -1,7 +1,6 @@ { "name": "@rocket.chat/ddp-client", - "private": true, - "version": "0.2.23", + "version": "0.2.24", "devDependencies": { "@swc/core": "^1.3.95", "@swc/jest": "^0.2.29", diff --git a/ee/packages/license/CHANGELOG.md b/ee/packages/license/CHANGELOG.md index 603f131dc407..80f539b4ed74 100644 --- a/ee/packages/license/CHANGELOG.md +++ b/ee/packages/license/CHANGELOG.md @@ -1,5 +1,41 @@ # @rocket.chat/license +## 0.1.15 + +### Patch Changes + +-
Updated dependencies [ff4e396416, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 +
+ +## 0.1.15-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 +
+ +## 0.1.15-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 +
+ +## 0.1.15-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 +
+ ## 0.1.14 ### Patch Changes diff --git a/ee/packages/license/package.json b/ee/packages/license/package.json index a07a8db51af0..6dc46eea1cf8 100644 --- a/ee/packages/license/package.json +++ b/ee/packages/license/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/license", - "version": "0.1.14", + "version": "0.1.15", "private": true, "devDependencies": { "@swc/core": "^1.3.95", diff --git a/ee/packages/omnichannel-services/CHANGELOG.md b/ee/packages/omnichannel-services/CHANGELOG.md index e9364326e949..15f0fb538132 100644 --- a/ee/packages/omnichannel-services/CHANGELOG.md +++ b/ee/packages/omnichannel-services/CHANGELOG.md @@ -1,5 +1,69 @@ # @rocket.chat/omnichannel-services +## 0.1.15 + +### Patch Changes + +- ([#32311](https://github.com/RocketChat/Rocket.Chat/pull/32311)) Fixed multiple issues with PDF generation logic when a quoted message was too big to fit in one single page. This was causing an internal infinite loop within the library (as it tried to make it fit, failing and then trying to fit on next page where the same happened thus causing a loop). + The library was not able to break down some nested views and thus was trying to fit the whole quote on one single page. Logic was updated to allow wrapping of the contents when messages are quoted (so they can span multiple lines) and removed a bunch of unnecesary views from the code. +- ([#32318](https://github.com/RocketChat/Rocket.Chat/pull/32318)) Fixed error handling for files bigger than NATS max allowed payload. This should prevent PDFs from erroring out when generating from rooms that contain heavy images. + +-
Updated dependencies [ff4e396416, ad86761209, f83bd56cc5, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/core-services@0.3.15 + - @rocket.chat/pdf-worker@0.0.39 + - @rocket.chat/rest-typings@6.9.0 + - @rocket.chat/model-typings@0.4.1 + - @rocket.chat/models@0.0.39 +
+ +## 0.1.15-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/rest-typings@6.9.0-rc.2 + - @rocket.chat/pdf-worker@0.0.39-rc.2 + - @rocket.chat/core-services@0.3.15-rc.2 + - @rocket.chat/model-typings@0.4.1-rc.2 + - @rocket.chat/models@0.0.39-rc.2 +
+ +## 0.1.15-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/rest-typings@6.9.0-rc.1 + - @rocket.chat/pdf-worker@0.0.39-rc.1 + - @rocket.chat/core-services@0.3.15-rc.1 + - @rocket.chat/model-typings@0.4.1-rc.1 + - @rocket.chat/models@0.0.39-rc.1 +
+ +## 0.1.15-rc.0 + +### Patch Changes + +- ([#32311](https://github.com/RocketChat/Rocket.Chat/pull/32311)) Fixed multiple issues with PDF generation logic when a quoted message was too big to fit in one single page. This was causing an internal infinite loop within the library (as it tried to make it fit, failing and then trying to fit on next page where the same happened thus causing a loop). + The library was not able to break down some nested views and thus was trying to fit the whole quote on one single page. Logic was updated to allow wrapping of the contents when messages are quoted (so they can span multiple lines) and removed a bunch of unnecesary views from the code. +- ([#32318](https://github.com/RocketChat/Rocket.Chat/pull/32318)) Fixed error handling for files bigger than NATS max allowed payload. This should prevent PDFs from erroring out when generating from rooms that contain heavy images. + +-
Updated dependencies [ff4e396416, ad86761209, f83bd56cc5, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/core-services@0.3.15-rc.0 + - @rocket.chat/pdf-worker@0.0.39-rc.0 + - @rocket.chat/rest-typings@6.9.0-rc.0 + - @rocket.chat/model-typings@0.4.1-rc.0 + - @rocket.chat/models@0.0.39-rc.0 +
+ ## 0.1.14 ### Patch Changes diff --git a/ee/packages/omnichannel-services/package.json b/ee/packages/omnichannel-services/package.json index a9a99ff25fd7..bea077c18386 100644 --- a/ee/packages/omnichannel-services/package.json +++ b/ee/packages/omnichannel-services/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/omnichannel-services", - "version": "0.1.14", + "version": "0.1.15", "private": true, "devDependencies": { "@rocket.chat/eslint-config": "workspace:^", diff --git a/ee/packages/pdf-worker/CHANGELOG.md b/ee/packages/pdf-worker/CHANGELOG.md index 5cd81d9558ac..ee34d97dc362 100644 --- a/ee/packages/pdf-worker/CHANGELOG.md +++ b/ee/packages/pdf-worker/CHANGELOG.md @@ -1,5 +1,45 @@ # @rocket.chat/pdf-worker +## 0.0.39 + +### Patch Changes + +- ([#32311](https://github.com/RocketChat/Rocket.Chat/pull/32311)) Fixed multiple issues with PDF generation logic when a quoted message was too big to fit in one single page. This was causing an internal infinite loop within the library (as it tried to make it fit, failing and then trying to fit on next page where the same happened thus causing a loop). + The library was not able to break down some nested views and thus was trying to fit the whole quote on one single page. Logic was updated to allow wrapping of the contents when messages are quoted (so they can span multiple lines) and removed a bunch of unnecesary views from the code. +-
Updated dependencies [ff4e396416, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 +
+ +## 0.0.39-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 +
+ +## 0.0.39-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 +
+ +## 0.0.39-rc.0 + +### Patch Changes + +- ([#32311](https://github.com/RocketChat/Rocket.Chat/pull/32311)) Fixed multiple issues with PDF generation logic when a quoted message was too big to fit in one single page. This was causing an internal infinite loop within the library (as it tried to make it fit, failing and then trying to fit on next page where the same happened thus causing a loop). + The library was not able to break down some nested views and thus was trying to fit the whole quote on one single page. Logic was updated to allow wrapping of the contents when messages are quoted (so they can span multiple lines) and removed a bunch of unnecesary views from the code. +-
Updated dependencies [ff4e396416, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 +
+ ## 0.0.38 ### Patch Changes diff --git a/ee/packages/pdf-worker/package.json b/ee/packages/pdf-worker/package.json index c2e3513b6aec..71a94eee43b5 100644 --- a/ee/packages/pdf-worker/package.json +++ b/ee/packages/pdf-worker/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/pdf-worker", - "version": "0.0.38", + "version": "0.0.39", "private": true, "devDependencies": { "@storybook/addon-essentials": "~6.5.16", diff --git a/ee/packages/presence/CHANGELOG.md b/ee/packages/presence/CHANGELOG.md index faae6ee61368..e96a8365cd10 100644 --- a/ee/packages/presence/CHANGELOG.md +++ b/ee/packages/presence/CHANGELOG.md @@ -1,5 +1,49 @@ # @rocket.chat/presence +## 0.1.15 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/core-services@0.3.15 + - @rocket.chat/models@0.0.39 +
+ +## 0.1.15-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/core-services@0.3.15-rc.2 + - @rocket.chat/models@0.0.39-rc.2 +
+ +## 0.1.15-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/core-services@0.3.15-rc.1 + - @rocket.chat/models@0.0.39-rc.1 +
+ +## 0.1.15-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, ad86761209, 724ba3a729, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/core-services@0.3.15-rc.0 + - @rocket.chat/models@0.0.39-rc.0 +
+ ## 0.1.14 ### Patch Changes diff --git a/ee/packages/presence/package.json b/ee/packages/presence/package.json index d4b102247d9a..4e609c5d954b 100644 --- a/ee/packages/presence/package.json +++ b/ee/packages/presence/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/presence", - "version": "0.1.14", + "version": "0.1.15", "private": true, "devDependencies": { "@babel/core": "~7.22.20", diff --git a/ee/packages/ui-theming/package.json b/ee/packages/ui-theming/package.json index 487e497d14c8..437f1fda92ab 100644 --- a/ee/packages/ui-theming/package.json +++ b/ee/packages/ui-theming/package.json @@ -4,9 +4,9 @@ "private": true, "devDependencies": { "@rocket.chat/css-in-js": "~0.31.25", - "@rocket.chat/fuselage": "^0.53.7", + "@rocket.chat/fuselage": "^0.54.2", "@rocket.chat/fuselage-hooks": "^0.33.1", - "@rocket.chat/icons": "^0.35.0", + "@rocket.chat/icons": "^0.36.0", "@rocket.chat/ui-contexts": "workspace:~", "@storybook/addon-actions": "~6.5.16", "@storybook/addon-docs": "~6.5.16", diff --git a/package.json b/package.json index fa35a133961e..c77da78c94be 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rocket.chat", - "version": "6.9.0-develop", + "version": "6.10.0-develop", "description": "Rocket.Chat Monorepo", "main": "index.js", "private": true, diff --git a/packages/apps/CHANGELOG.md b/packages/apps/CHANGELOG.md index 2eda0bcd9fb0..f58d8fbfe387 100644 --- a/packages/apps/CHANGELOG.md +++ b/packages/apps/CHANGELOG.md @@ -1,5 +1,45 @@ # @rocket.chat/apps +## 0.0.6 + +### Patch Changes + +-
Updated dependencies [ff4e396416, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/model-typings@0.4.1 +
+ +## 0.0.6-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/model-typings@0.4.1-rc.2 +
+ +## 0.0.6-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/model-typings@0.4.1-rc.1 +
+ +## 0.0.6-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/model-typings@0.4.1-rc.0 +
+ ## 0.0.5 ### Patch Changes diff --git a/packages/apps/package.json b/packages/apps/package.json index fd657d4382f8..ee99ba288fab 100644 --- a/packages/apps/package.json +++ b/packages/apps/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/apps", - "version": "0.0.5", + "version": "0.0.6", "private": true, "devDependencies": { "@types/jest": "~29.5.7", diff --git a/packages/core-services/CHANGELOG.md b/packages/core-services/CHANGELOG.md index 38f0c44cb8ac..779db0d7b4ca 100644 --- a/packages/core-services/CHANGELOG.md +++ b/packages/core-services/CHANGELOG.md @@ -1,5 +1,59 @@ # @rocket.chat/core-services +## 0.3.15 + +### Patch Changes + +- ([#32311](https://github.com/RocketChat/Rocket.Chat/pull/32311)) Fixed multiple issues with PDF generation logic when a quoted message was too big to fit in one single page. This was causing an internal infinite loop within the library (as it tried to make it fit, failing and then trying to fit on next page where the same happened thus causing a loop). + The library was not able to break down some nested views and thus was trying to fit the whole quote on one single page. Logic was updated to allow wrapping of the contents when messages are quoted (so they can span multiple lines) and removed a bunch of unnecesary views from the code. +- ([#32318](https://github.com/RocketChat/Rocket.Chat/pull/32318)) Fixed error handling for files bigger than NATS max allowed payload. This should prevent PDFs from erroring out when generating from rooms that contain heavy images. + +-
Updated dependencies [ff4e396416, f83bd56cc5, ee5cdfc367, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/rest-typings@6.9.0 + - @rocket.chat/ui-kit@0.34.0 + - @rocket.chat/models@0.0.39 +
+ +## 0.3.15-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/rest-typings@6.9.0-rc.2 + - @rocket.chat/models@0.0.39-rc.2 +
+ +## 0.3.15-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/rest-typings@6.9.0-rc.1 + - @rocket.chat/models@0.0.39-rc.1 +
+ +## 0.3.15-rc.0 + +### Patch Changes + +- ([#32311](https://github.com/RocketChat/Rocket.Chat/pull/32311)) Fixed multiple issues with PDF generation logic when a quoted message was too big to fit in one single page. This was causing an internal infinite loop within the library (as it tried to make it fit, failing and then trying to fit on next page where the same happened thus causing a loop). + The library was not able to break down some nested views and thus was trying to fit the whole quote on one single page. Logic was updated to allow wrapping of the contents when messages are quoted (so they can span multiple lines) and removed a bunch of unnecesary views from the code. +- ([#32318](https://github.com/RocketChat/Rocket.Chat/pull/32318)) Fixed error handling for files bigger than NATS max allowed payload. This should prevent PDFs from erroring out when generating from rooms that contain heavy images. + +-
Updated dependencies [ff4e396416, f83bd56cc5, ee5cdfc367, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/rest-typings@6.9.0-rc.0 + - @rocket.chat/ui-kit@0.34.0-rc.0 + - @rocket.chat/models@0.0.39-rc.0 +
+ ## 0.3.14 ### Patch Changes diff --git a/packages/core-services/package.json b/packages/core-services/package.json index d7a8fe6b78f1..6033814bf2fa 100644 --- a/packages/core-services/package.json +++ b/packages/core-services/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/core-services", - "version": "0.3.14", + "version": "0.3.15", "private": true, "devDependencies": { "@babel/core": "~7.22.20", @@ -36,7 +36,7 @@ "dependencies": { "@rocket.chat/apps-engine": "1.42.2", "@rocket.chat/core-typings": "workspace:^", - "@rocket.chat/icons": "^0.35.0", + "@rocket.chat/icons": "^0.36.0", "@rocket.chat/message-parser": "workspace:^", "@rocket.chat/models": "workspace:^", "@rocket.chat/rest-typings": "workspace:^", diff --git a/packages/core-typings/CHANGELOG.md b/packages/core-typings/CHANGELOG.md index 311b3bbefa88..cb92dfed9f7f 100644 --- a/packages/core-typings/CHANGELOG.md +++ b/packages/core-typings/CHANGELOG.md @@ -1,5 +1,39 @@ # @rocket.chat/core-typings +## 6.9.0 + +### Minor Changes + +- ([#31917](https://github.com/RocketChat/Rocket.Chat/pull/31917)) Introduced a tab layout to the users page and implemented a tab called "All" that lists all users. + +- ([#32298](https://github.com/RocketChat/Rocket.Chat/pull/32298)) Added "Rocket.Chat Cloud Workspace ID" to workspace statistics page + +### Patch Changes + +-
Updated dependencies [ee5cdfc367]: + + - @rocket.chat/ui-kit@0.34.0 +
+ +## 6.9.0-rc.2 + +## 6.9.0-rc.1 + +## 6.9.0-rc.0 + +### Minor Changes + +- ([#31917](https://github.com/RocketChat/Rocket.Chat/pull/31917)) Introduced a tab layout to the users page and implemented a tab called "All" that lists all users. + +- ([#32298](https://github.com/RocketChat/Rocket.Chat/pull/32298)) Added "Rocket.Chat Cloud Workspace ID" to workspace statistics page + +### Patch Changes + +-
Updated dependencies [ee5cdfc367]: + + - @rocket.chat/ui-kit@0.34.0-rc.0 +
+ ## 6.8.0 ### Minor Changes diff --git a/packages/core-typings/package.json b/packages/core-typings/package.json index 8da547209212..9256b3e8b6e7 100644 --- a/packages/core-typings/package.json +++ b/packages/core-typings/package.json @@ -1,8 +1,7 @@ { "$schema": "https://json.schemastore.org/package", "name": "@rocket.chat/core-typings", - "private": true, - "version": "6.9.0-develop", + "version": "6.10.0-develop", "devDependencies": { "@rocket.chat/eslint-config": "workspace:^", "eslint": "~8.45.0", @@ -24,7 +23,7 @@ ], "dependencies": { "@rocket.chat/apps-engine": "1.42.2", - "@rocket.chat/icons": "^0.35.0", + "@rocket.chat/icons": "^0.36.0", "@rocket.chat/message-parser": "workspace:^", "@rocket.chat/ui-kit": "workspace:~" }, diff --git a/packages/cron/CHANGELOG.md b/packages/cron/CHANGELOG.md index 797d15348f5d..b79a1aa46e9d 100644 --- a/packages/cron/CHANGELOG.md +++ b/packages/cron/CHANGELOG.md @@ -1,5 +1,45 @@ # @rocket.chat/cron +## 0.0.35 + +### Patch Changes + +-
Updated dependencies [ff4e396416, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/models@0.0.39 +
+ +## 0.0.35-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/models@0.0.39-rc.2 +
+ +## 0.0.35-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/models@0.0.39-rc.1 +
+ +## 0.0.35-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/models@0.0.39-rc.0 +
+ ## 0.0.34 ### Patch Changes diff --git a/packages/cron/package.json b/packages/cron/package.json index a9a4424dafe9..1755e8a33a2b 100644 --- a/packages/cron/package.json +++ b/packages/cron/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/cron", - "version": "0.0.34", + "version": "0.0.35", "private": true, "devDependencies": { "@types/jest": "~29.5.7", diff --git a/packages/fuselage-ui-kit/CHANGELOG.md b/packages/fuselage-ui-kit/CHANGELOG.md index 7733e8063e61..21652a54903b 100644 --- a/packages/fuselage-ui-kit/CHANGELOG.md +++ b/packages/fuselage-ui-kit/CHANGELOG.md @@ -1,5 +1,71 @@ # Change Log +## 7.0.0 + +### Minor Changes + +- ([#31918](https://github.com/RocketChat/Rocket.Chat/pull/31918)) Introduced new elements for apps to select channels + +### Patch Changes + +- ([#32327](https://github.com/RocketChat/Rocket.Chat/pull/32327)) Fix translation param on video conf joined message + +-
Updated dependencies [ff4e396416, ee5cdfc367, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/ui-kit@0.34.0 + - @rocket.chat/gazzodown@7.0.0 + - @rocket.chat/ui-contexts@7.0.0 + - @rocket.chat/ui-avatar@3.0.0 + - @rocket.chat/ui-video-conf@7.0.0 +
+ +## 7.0.0-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/gazzodown@7.0.0-rc.2 + - @rocket.chat/ui-contexts@7.0.0-rc.2 + - @rocket.chat/ui-avatar@3.0.0-rc.2 + - @rocket.chat/ui-video-conf@7.0.0-rc.2 +
+ +## 7.0.0-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/gazzodown@7.0.0-rc.1 + - @rocket.chat/ui-contexts@7.0.0-rc.1 + - @rocket.chat/ui-avatar@3.0.0-rc.1 + - @rocket.chat/ui-video-conf@7.0.0-rc.1 +
+ +## 7.0.0-rc.0 + +### Minor Changes + +- ([#31918](https://github.com/RocketChat/Rocket.Chat/pull/31918)) Introduced new elements for apps to select channels + +### Patch Changes + +- ([#32327](https://github.com/RocketChat/Rocket.Chat/pull/32327)) Fix translation param on video conf joined message + +-
Updated dependencies [ff4e396416, ee5cdfc367, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/ui-kit@0.34.0-rc.0 + - @rocket.chat/gazzodown@7.0.0-rc.0 + - @rocket.chat/ui-contexts@7.0.0-rc.0 + - @rocket.chat/ui-avatar@3.0.0-rc.0 + - @rocket.chat/ui-video-conf@7.0.0-rc.0 +
+ ## 6.0.0 ### Patch Changes diff --git a/packages/fuselage-ui-kit/package.json b/packages/fuselage-ui-kit/package.json index 5fe8960b2589..25d44e876dff 100644 --- a/packages/fuselage-ui-kit/package.json +++ b/packages/fuselage-ui-kit/package.json @@ -1,7 +1,7 @@ { "name": "@rocket.chat/fuselage-ui-kit", "private": true, - "version": "6.0.0", + "version": "7.0.0", "description": "UiKit elements for Rocket.Chat Apps built under Fuselage design system", "homepage": "https://rocketchat.github.io/Rocket.Chat.Fuselage/", "author": { @@ -50,10 +50,10 @@ "@rocket.chat/icons": "*", "@rocket.chat/prettier-config": "*", "@rocket.chat/styled": "*", - "@rocket.chat/ui-avatar": "2.0.0", - "@rocket.chat/ui-contexts": "6.0.0", - "@rocket.chat/ui-kit": "0.33.0", - "@rocket.chat/ui-video-conf": "6.0.0", + "@rocket.chat/ui-avatar": "3.0.0", + "@rocket.chat/ui-contexts": "7.0.0", + "@rocket.chat/ui-kit": "0.34.0", + "@rocket.chat/ui-video-conf": "7.0.0", "@tanstack/react-query": "*", "react": "*", "react-dom": "*" @@ -66,10 +66,10 @@ "@rocket.chat/apps-engine": "^1.42.2", "@rocket.chat/core-typings": "workspace:^", "@rocket.chat/eslint-config": "workspace:^", - "@rocket.chat/fuselage": "^0.53.7", + "@rocket.chat/fuselage": "^0.54.2", "@rocket.chat/fuselage-hooks": "^0.33.1", "@rocket.chat/fuselage-polyfills": "~0.31.25", - "@rocket.chat/icons": "^0.35.0", + "@rocket.chat/icons": "^0.36.0", "@rocket.chat/mock-providers": "workspace:^", "@rocket.chat/prettier-config": "~0.31.25", "@rocket.chat/styled": "~0.31.25", @@ -110,7 +110,7 @@ "typescript": "~5.3.3" }, "dependencies": { - "@rocket.chat/core-typings": "*", + "@rocket.chat/core-typings": "workspace:^", "@rocket.chat/gazzodown": "workspace:^", "@rocket.chat/ui-kit": "workspace:~", "tslib": "^2.5.3" diff --git a/packages/gazzodown/CHANGELOG.md b/packages/gazzodown/CHANGELOG.md index 828981eb3809..61620a5e7eb8 100644 --- a/packages/gazzodown/CHANGELOG.md +++ b/packages/gazzodown/CHANGELOG.md @@ -1,5 +1,49 @@ # @rocket.chat/gazzodown +## 7.0.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/ui-contexts@7.0.0 + - @rocket.chat/ui-client@7.0.0 +
+ +## 7.0.0-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/ui-contexts@7.0.0-rc.2 + - @rocket.chat/ui-client@7.0.0-rc.2 +
+ +## 7.0.0-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/ui-contexts@7.0.0-rc.1 + - @rocket.chat/ui-client@7.0.0-rc.1 +
+ +## 7.0.0-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/ui-contexts@7.0.0-rc.0 + - @rocket.chat/ui-client@7.0.0-rc.0 +
+ ## 6.0.0 ### Patch Changes diff --git a/packages/gazzodown/package.json b/packages/gazzodown/package.json index 435c984008a5..0ce09b0aa79b 100644 --- a/packages/gazzodown/package.json +++ b/packages/gazzodown/package.json @@ -1,12 +1,12 @@ { "name": "@rocket.chat/gazzodown", - "version": "6.0.0", + "version": "7.0.0", "private": true, "devDependencies": { "@babel/core": "~7.22.20", "@rocket.chat/core-typings": "workspace:^", "@rocket.chat/css-in-js": "~0.31.25", - "@rocket.chat/fuselage": "^0.53.7", + "@rocket.chat/fuselage": "^0.54.2", "@rocket.chat/fuselage-tokens": "^0.33.1", "@rocket.chat/message-parser": "workspace:^", "@rocket.chat/styled": "~0.31.25", @@ -71,8 +71,8 @@ "@rocket.chat/fuselage-tokens": "*", "@rocket.chat/message-parser": "0.31.29", "@rocket.chat/styled": "*", - "@rocket.chat/ui-client": "6.0.0", - "@rocket.chat/ui-contexts": "6.0.0", + "@rocket.chat/ui-client": "7.0.0", + "@rocket.chat/ui-contexts": "7.0.0", "katex": "*", "react": "*" }, diff --git a/packages/i18n/CHANGELOG.md b/packages/i18n/CHANGELOG.md index c1488a9ce8ca..53b9795af3f7 100644 --- a/packages/i18n/CHANGELOG.md +++ b/packages/i18n/CHANGELOG.md @@ -1,5 +1,29 @@ # @rocket.chat/i18n +## 0.4.0 + +### Minor Changes + +- ([#32298](https://github.com/RocketChat/Rocket.Chat/pull/32298)) Added "Rocket.Chat Cloud Workspace ID" to workspace statistics page + +### Patch Changes + +- ([#31917](https://github.com/RocketChat/Rocket.Chat/pull/31917)) Introduced a tab layout to the users page and implemented a tab called "All" that lists all users. + +- ([#32182](https://github.com/RocketChat/Rocket.Chat/pull/32182)) Fixed an issue with object storage settings that was not allowing admins to decide if files generated via "Export conversation" feature were being proxied through server or not. + +## 0.4.0-rc.0 + +### Minor Changes + +- ([#32298](https://github.com/RocketChat/Rocket.Chat/pull/32298)) Added "Rocket.Chat Cloud Workspace ID" to workspace statistics page + +### Patch Changes + +- ([#31917](https://github.com/RocketChat/Rocket.Chat/pull/31917)) Introduced a tab layout to the users page and implemented a tab called "All" that lists all users. + +- ([#32182](https://github.com/RocketChat/Rocket.Chat/pull/32182)) Fixed an issue with object storage settings that was not allowing admins to decide if files generated via "Export conversation" feature were being proxied through server or not. + ## 0.3.0 ### Minor Changes diff --git a/packages/i18n/package.json b/packages/i18n/package.json index 38a4c434b12c..629d48364e80 100644 --- a/packages/i18n/package.json +++ b/packages/i18n/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/i18n", - "version": "0.3.0", + "version": "0.4.0", "private": true, "devDependencies": { "@babel/core": "~7.22.20", diff --git a/packages/i18n/src/locales/ar.i18n.json b/packages/i18n/src/locales/ar.i18n.json index e8c5b3c62ab1..85dfe30a4839 100644 --- a/packages/i18n/src/locales/ar.i18n.json +++ b/packages/i18n/src/locales/ar.i18n.json @@ -277,6 +277,7 @@ "add-livechat-department-agents_description": "إذن لإضافة وكلاء للقنوات متعددة الاتجاهات إلى الأقسام", "add-oauth-service": "إضافة خدمة Oauth", "add-oauth-service_description": "إذن لإضافة خدمة Oauth جديدة", + "Calls_in_queue_many": "{{count}} من المكالمات الانتظار", "add-user": "إضافة مستخدم", "add-user_description": "إذن لإضافة مستخدمين جدد إلى الخادم عبر شاشة المستخدمين", "add-user-to-any-c-room": "إضافة مستخدم إلى أي Channel عامة", @@ -296,6 +297,7 @@ "additional_integrations_Bots": "إذا كنت تبحث عن كيفية دمج الروبوت الخاص بك، فلن تجد أفضل من محول Hubot الخاص بنا. https://github.com/RocketChat/hubot-rocketchat", "Admin_disabled_encryption": "لم يقوم المسؤول لديك بتمكين التشفير بين الوحدات الطرفية.", "Admin_Info": "معلومات المسؤول", + "Calls_in_queue_few": "{{count}} من المكالمات الانتظار", "Administration": "الإدارة", "Adult_images_are_not_allowed": "غير مسموح بالصور الخاصة بالكبار", "Aerospace_and_Defense": "الفضاء والدفاع", @@ -335,7 +337,6 @@ "All_messages": "كل الرسائل", "All_users": "جميع المستخدمين", "All_users_in_the_channel_can_write_new_messages": "يمكن لجميع المستخدمين في القناة كتابة رسائل جديدة", - "Calls_in_queue_many": "{{count}} من المكالمات الانتظار", "Allow_collect_and_store_HTTP_header_informations": "السماح بجمع وتخزين معلومات عنوان HTTP", "Allow_collect_and_store_HTTP_header_informations_description": "يحدد هذا الإعداد ما إذا كان مسموحًا لـ Livechat بتخزين المعلومات التي يتم جمعها من بيانات عنوان HTTP أم لا، مثل عنوان IP، ووكيل المستخدم، وما إلى ذلك.", "Allow_Invalid_SelfSigned_Certs": "السماح بالشهادات الموقعة ذاتيًا غير الصالحة", @@ -362,7 +363,6 @@ "Animals_and_Nature": "الحيوانات والطبيعة", "Announcement": "إعلان", "Anonymous": "غير شخصي", - "Calls_in_queue_few": "{{count}} من المكالمات الانتظار", "Answer_call": "الرد على المكالمة", "API": "واجهة برمجة التطبيقات", "API_Add_Personal_Access_Token": "إضافة رمز مميز جديد للوصول الشخصي", @@ -942,6 +942,7 @@ "Contact_not_found": "لم يتم العثور على جهة الاتصال", "Contact_Profile": "الملف الشخصي لجهة الاتصال", "Contact_Info": "معلومات جهة الاتصال", + "message_counter_many": "{{count}} رسائل", "Content": "المحتوى", "Continue": "متابعة", "Continuous_sound_notifications_for_new_livechat_room": "إشعارات صوتية مستمرة لغرفة القناة متعددة الاتجاهاهت الجديدة", @@ -956,6 +957,7 @@ "Conversations": "المحادثات", "Conversations_per_day": "المحادثات لكل يوم", "Convert": "تحويل", + "meteor_status_reconnect_in_many": "المحاولة مرة أخرى خلال {{count}} من الثواني...", "Convert_Ascii_Emojis": "تحويل ASCII إلى رمز تعبيري", "Convert_to_channel": "التحويل إلى Channel", "Converting_channel_to_a_team": "أنت تقوم بتحويل Channel هذه إلى فريق. سيتم الاحتفاظ بجميع الأعضاء.", @@ -1031,6 +1033,7 @@ "Country_Denmark": "الدنمارك", "Country_Djibouti": "جيبوتي", "Country_Dominica": "دومينيكا", + "message_counter_few": "{{count}} رسائل", "Country_Dominican_Republic": "جمهورية الدومنيكان", "Country_Ecuador": "الإكوادور", "Country_Egypt": "مصر", @@ -1066,6 +1069,7 @@ "Country_Heard_Island_and_Mcdonald_Islands": "جزيرة هيرد وجزر ماكدونالد", "Country_Holy_See_Vatican_City_State": "الكرسي الرسولي (دولة الفاتيكان)", "Country_Honduras": "هندوراس", + "meteor_status_reconnect_in_few": "المحاولة مرة أخرى خلال {{count}} من الثواني...", "Country_Hong_Kong": "هونغ كونغ", "Country_Hungary": "هنغاريا", "Country_Iceland": "أيسلندا", @@ -1373,7 +1377,6 @@ "Desktop_Notifications_Duration_Description": "عدد الثواني اللازمة لعرض إشعار سطح المكتب. قد يؤثر ذلك في مركز إشعارات OS X. أدخل 0 لاستخدام إعدادات المتصفح الافتراضية دون التأثير في مركز إشعارات OS X.", "Desktop_Notifications_Enabled": "إشعارات سطح المكتب ممكّنة", "Desktop_Notifications_Not_Enabled": "إشعارات سطح المكتب غير ممكّنة", - "message_counter_many": "{{count}} رسائل", "Details": "التفاصيل", "line": "السطر", "Device_Management_IP": " عنوان IP", @@ -1393,7 +1396,6 @@ "Direct_Reply_Debug_Description": "[تحذير] سيترتب على تمكين وضع التصحيح عرض \"كلمة المرور بنص عادي\" في وحدة تحكم المسؤول.", "Direct_Reply_Delete": "حذف رسائل البريد الإلكتروني", "Direct_Reply_Delete_Description": "[تنبيه!] إذا تم تفعيل هذا الخيار، فسيتم حذف جميع الرسائل غير المقروءة نهائيًا، ومن بينها الرسائل التي ليست ردودًا مباشرة. عندئذٍ يكون صندوق البريد الإلكتروني الذي تم تكوينه فارغًا دائمًا ولا يستطيع إنسان معالجته \"بشكل متوازٍ\".", - "meteor_status_reconnect_in_many": "المحاولة مرة أخرى خلال {{count}} من الثواني...", "Direct_Reply_Enable": "تمكين الرد المباشر", "Direct_Reply_Enable_Description": "[تنبيه!] إذا تم تمكين \"الرد المباشر\"، فإن Rocket.Chat سيتحكم في صندوق البريد الإلكتروني الذي تم تكوينه. يتم استرداد جميع رسائل البريد الإلكتروني غير المقروءة، ووضع علامة \"مقروءة\" عليها ومعالجتها. يجب تنشيط \"الرد المباشر\" فقط إذا كان صندوق البريد المستخدم مخصصًا حصريًا للوصول بواسطة Rocket.Chat ولم يقم إنسان بقراءته/معالجته \"بالتوازي\".", "Direct_Reply_Frequency": "معدل التكرار التحقق من البريد الإلكتروني", @@ -1479,7 +1481,6 @@ "Markdown_Marked_Tables": "تمكين الجداول المحددة", "duplicated-account": "حساب مكرر", "E2E Encryption": "التشفير بين الطرفيات", - "message_counter_few": "{{count}} رسائل", "Markdown_Parser": "محلل Markdown", "Markdown_SupportSchemesForLink": "مخططات دعم Markdown للرابط", "Markdown_SupportSchemesForLink_Description": "قائمة المخططات المسموح بها مفصولة بفواصل", @@ -1525,7 +1526,6 @@ "edit-other-user-active-status_description": "إذن لتمكين أو تعطيل الحسابات الأخرى", "edit-other-user-avatar": "تحرير الصورة الرمزية للمستخدم الآخر", "edit-other-user-avatar_description": "إذن لتغيير الصورة الرمزية للمستخدم الآخر.", - "meteor_status_reconnect_in_few": "المحاولة مرة أخرى خلال {{count}} من الثواني...", "edit-other-user-e2ee": "تحرير التشفير بين الطرفيات للمستخدم الآخر", "edit-other-user-e2ee_description": "إذن لتعديل التشفير بين الطرفيات للمستخدمين الآخرين", "edit-other-user-info": "تحرير معلومات المستخدمين الآخرين", @@ -1608,8 +1608,10 @@ "EncryptionKey_Change_Disabled": "لا يمكنك تعيين كلمة مرور لمفتاح التشفير الخاص بك لأن مفتاحك الخاص غير موجود على هذا العميل. لتعيين كلمة مرور جديدة، يلزمك تحميل مفتاحك الخاص باستخدام كلمة مرورك الحالية أو استخدام وكيل سبق رفع المفتاح لديه.", "End": "إنهاء", "End_call": "إنهاء مكالمة", + "message_counter_two": "{{count}} رسائل", "Expand_view": "توسيع العرض", "Explore_marketplace": "استكشاف السوق", + "message_counter_zero": "{{count}} رسائل", "Explore_the_marketplace_to_find_awesome_apps": "استكشف السوق للعثور على تطبيقات رائعة لـ Rocket.Chat", "Export": "تصدير", "End_Call": "إنهاء مكالمة", @@ -1658,7 +1660,9 @@ "error-canned-response-not-found": "لم يتم العثور على ردود مسجلة", "error-cannot-delete-app-user": "غير مسموح بحذف مستخدم التطبيق، قم بإلغاء تثبيت التطبيق المقابل لإزالته.", "error-cant-invite-for-direct-room": "لا يمكن دعوة المستخدم في الغرفة المباشرة", + "meteor_status_reconnect_in_two": "المحاولة مرة أخرى خلال {{count}} من الثواني...", "error-channels-setdefault-is-same": "الإعداد الافتراضي للقناة هو نفسه الذي سيتم تغييره إليه.", + "meteor_status_reconnect_in_zero": "المحاولة مرة أخرى خلال {{count}} من الثواني...", "error-channels-setdefault-missing-default-param": "يلزم توفير bodyParam \"الافتراضية\"", "error-could-not-change-email": "تعذر تغيير البريد الإلكتروني", "error-could-not-change-name": "تعذر تغيير الاسم", @@ -1949,11 +1953,9 @@ "FileUpload_S3_Proxy_Uploads": "عمليات الرفع الخاصة بالوكيل", "FileUpload_S3_Proxy_Uploads_Description": "إرسال ملف الرفع الخاص بالوكيل من خلال الخادم الخاص بك بدلاً من الوصول المباشر إلى عنوان URL الخاص بالأصل", "FileUpload_S3_Region": "المنطقة", - "message_counter_two": "{{count}} رسائل", "FileUpload_S3_SignatureVersion": "إصدار التوقيع", "FileUpload_S3_URLExpiryTimeSpan": "فترة انتهاء صلاحية عناوين URL", "FileUpload_S3_URLExpiryTimeSpan_Description": "الوقت الذي لن تصبح بعده عناوين URL التي تنشئها Amazon S3 صالحة (بالثواني). إذا تم التعيين على أقل من 5 ثوانٍ، فسيتم تجاهل هذا الحقل.", - "message_counter_zero": "{{count}} رسائل", "FileUpload_Storage_Type": "نوع التخزين", "FileUpload_Webdav_Password": "كلمة مرور WebDAV", "FileUpload_Webdav_Proxy_Avatars": "الصور الرمزية للوكيل", @@ -2020,8 +2022,6 @@ "Full_Screen": "ملء الشاشة", "Gaming": "الألعاب", "General": "عام", - "meteor_status_reconnect_in_two": "المحاولة مرة أخرى خلال {{count}} من الثواني...", - "meteor_status_reconnect_in_zero": "المحاولة مرة أخرى خلال {{count}} من الثواني...", "Generate_new_key": "إنشاء مفتاح جديد", "Generate_New_Link": "إنشاء رابط جديد", "Generating_key": "يتم إنشاء مفتاح", diff --git a/packages/i18n/src/locales/cs.i18n.json b/packages/i18n/src/locales/cs.i18n.json index 4fd748f64f42..a02152a66277 100644 --- a/packages/i18n/src/locales/cs.i18n.json +++ b/packages/i18n/src/locales/cs.i18n.json @@ -759,6 +759,7 @@ "Contact": "Kontakt", "Contact_Chat_History": "Historie kontaktu", "Contains_Security_Fixes": "Obsahuje opravy zabezpečení", + "message_counter_many": "{{count}} zpráv(y)", "Content": "Obsah", "Continue": "Pokračovat", "Continuous_sound_notifications_for_new_livechat_room": "Trvalé zvukové oznámení pro novou Omnichannel místnost", @@ -772,6 +773,7 @@ "conversation_with_s": "konverzace s %s", "Conversations": "Konverzace", "Conversations_per_day": "Konverzace za den", + "meteor_status_reconnect_in_many": "zkusím znovu za {{count}} sekund...", "Convert_Ascii_Emojis": "Převod ASCII na Emoji", "Copied": "Zkopírováno", "Copy": "Kopírovat", @@ -842,6 +844,7 @@ "Country_Denmark": "Dánsko", "Country_Djibouti": "Džibutsko", "Country_Dominica": "Dominika", + "message_counter_few": "{{count}} zpráv(y)", "Country_Dominican_Republic": "Dominikánská republika", "Country_Ecuador": "Ekvádor", "Country_Egypt": "Egypt", @@ -877,6 +880,7 @@ "Country_Heard_Island_and_Mcdonald_Islands": "Heardův ostrov a McDonaldovy ostrovy", "Country_Holy_See_Vatican_City_State": "Svatý stolec (Vatikánský městský stát)", "Country_Honduras": "Honduras", + "meteor_status_reconnect_in_few": "zkusím znovu za {{count}} sekund...", "Country_Hong_Kong": "Hongkong", "Country_Hungary": "Maďarsko", "Country_Iceland": "Island", @@ -1165,7 +1169,6 @@ "Desktop_Notifications_Duration_Description": "Délka zobrazení oznámení (v sekundách). Toto může ovlivnit nastevení OS X Oznamovacího centra. Zadejte 0 pro použítí výchozí nastavení prohlížeče/notifikačního centra OS X", "Desktop_Notifications_Enabled": "Oznámení na ploše jsou povolena", "Desktop_Notifications_Not_Enabled": "Oznámení na ploše jsou povoleny", - "message_counter_many": "{{count}} zpráv(y)", "Details": "Detaily", "line": "řádek", "Different_Style_For_User_Mentions": "Odlišný styl pro zmínky", @@ -1183,7 +1186,6 @@ "Direct_Reply_Debug_Description": "[Pozor] Povolení Debug módu znamená zobrazení hesla v čitelné podobě v admin konzoli", "Direct_Reply_Delete": "Smazat e-maily", "Direct_Reply_Delete_Description": "[Pozor!] Je-li tato možnost aktivována, všechny nepřečtené zprávy budou neodvolatelně odstraněny, a to i ty, které nejsou přímými odpověďmi. Konfigurovaná e-mailová schránka je pak vždy prázdná a lidé ji NEmohou zpracovávat „paralelně“.", - "meteor_status_reconnect_in_many": "zkusím znovu za {{count}} sekund...", "Direct_Reply_Enable": "Povolit přímou odpověď", "Direct_Reply_Enable_Description": "[Pozor!] Pokud je povolená „Přímá odpověď“, bude Rocket.Chat ovládat nakonfigurovanou e-mailovou schránku. Všechny nepřečtené e-maily jsou načteny, označeny jako přečtené a zpracované. „Přímá odpověď“ by měla být aktivována pouze v případě, že použitá poštovní schránka je určena výhradně pro přístup na server Rocket.Chat a není člověkem „paralelně“ čtena/zpracována.", "Direct_Reply_Frequency": "Frekvenkce kontroly emailu", @@ -1260,7 +1262,6 @@ "Markdown_Marked_Tables": "Povolit značky tabulek", "duplicated-account": "Duplicitní účet", "E2E Encryption": "Šifrování E2E", - "message_counter_few": "{{count}} zpráv(y)", "Markdown_Parser": "Parser markdownu", "Markdown_SupportSchemesForLink": "Schémata používaná pro automatické odkazy markdown", "Markdown_SupportSchemesForLink_Description": "Čárkami oddělený seznam povolených schémat", @@ -1296,7 +1297,6 @@ "edit-other-user-active-status_description": "Právo povolit nebo zakázat jiné uživatelské účty", "edit-other-user-avatar": "Upravit avatar jiného uživatele", "edit-other-user-avatar_description": "Povolení změnit avatar jiného uživatele.", - "meteor_status_reconnect_in_few": "zkusím znovu za {{count}} sekund...", "edit-other-user-e2ee": "Upravit E2E šifrování jiného uživatele", "edit-other-user-e2ee_description": "Povolení spravovat E2E šifrování ostatních uživatelů", "edit-other-user-info": "Upravit informace uživatelů", diff --git a/packages/i18n/src/locales/es.i18n.json b/packages/i18n/src/locales/es.i18n.json index 8f6a9cd845f3..d79d3fa71cb1 100644 --- a/packages/i18n/src/locales/es.i18n.json +++ b/packages/i18n/src/locales/es.i18n.json @@ -15,9 +15,9 @@ "__username__is_no_longer__role__defined_by__user_by_": "{{username}} ya no es {{role}} (por {{user_by}})", "__username__was_set__role__by__user_by_": "{{username}} se ha establecido como {{role}} por {{user_by}}", "__count__without__department__": "{{count}} sin departamentos", - "__usersCount__member_joined_many": "{{count}} miembros se han unido", "__count__without__tags__": "{{count}} sin etiquetas", "__count__without__assignee__": "{{count}} sin un agente asignado", + "__usersCount__member_joined_many": "{{count}} miembros se han unido", "removed__username__as__role_": "se removió {{username}} como {{role}}", "set__username__as__role_": " se estableció a {{username}} como {{role}}", "This_room_encryption_has_been_enabled_by__username_": "El cifrado de esta sala ha sido habilitado por {{username}}", @@ -947,6 +947,7 @@ "Contact_not_found": "Contacto no encontrado", "Contact_Profile": "Perfil de contacto", "Contact_Info": "Información de contacto", + "message_counter_many": "{{count}} mensajes", "Content": "Contenido", "Continue": "Continuar", "Continuous_sound_notifications_for_new_livechat_room": "Notificaciones de sonido continuas para nueva sala de Omnichannel", @@ -961,6 +962,7 @@ "Conversations": "Conversaciones", "Conversations_per_day": "Conversaciones por día", "Convert": "Convertir", + "meteor_status_reconnect_in_many": "intentando de nuevo dentro de {{count}} segundos...", "Convert_Ascii_Emojis": "Convierte ASCII a emoji", "Convert_to_channel": "Convertir en Channel", "Converting_channel_to_a_team": "Vas a convertir este Channel en un equipo. Se conservarán todos los miembros.", @@ -1381,7 +1383,6 @@ "Desktop_Notifications_Duration_Description": "Segundos durante los que mostrar la notificación de escritorio. Esto puede afectar al Centro de notificaciones de OS X. Introduce 0 para usar la configuración por defecto del navegador y que no afecte al Centro de notificaciones de OS X.", "Desktop_Notifications_Enabled": "Las notificaciones de escritorio están habilitadas", "Desktop_Notifications_Not_Enabled": "Las notificaciones de escritorio no están habilitadas", - "message_counter_many": "{{count}} mensajes", "Details": "Detalles", "line": "línea", "Device_Management_IP": "IP", @@ -1400,7 +1401,6 @@ "Direct_Reply_Debug_Description": "[Beware] Habilitar el modo de depuración mostraría tu \"Contraseña de texto sin formato\" en la consola de administración.", "Direct_Reply_Delete": "Eliminar correos electrónicos", "Direct_Reply_Delete_Description": "[Attention!] Si esta opción está activada, todos los mensajes no leídos se eliminan irrevocablemente, incluso aquellos que no son respuestas directas. Así, el buzón de correo electrónico configurado está siempre vacío y ninguna persona puede procesarlo \"en paralelo\".", - "meteor_status_reconnect_in_many": "intentando de nuevo dentro de {{count}} segundos...", "Direct_Reply_Enable": "Habilitar respuesta directa", "Direct_Reply_Enable_Description": "[Attention!] Si la opción \"Respuesta directa\" está habilitada, Rocket.Chat controlará el buzón de correo electrónico configurado. Todos los correos electrónicos no leídos se recuperan, se marcan como leídos y se procesan. La opción \"Respuesta directa\" solo debe activarse si el buzón de correo usado está destinado exclusivamente al acceso por parte de Rocket.Chat y ninguna persona puede leerlo o procesarlo \"en paralelo\".", "Direct_Reply_Frequency": "Frecuencia de verificación de correo electrónico", @@ -1799,11 +1799,14 @@ "every_5_minutes": "Una vez cada 5 minutos", "every_10_seconds": "Una vez cada 10 segundos", "every_30_minutes": "Una vez cada 30 minutos", + "mentions_counter_many": "{{count}} menciones", "every_day": "Una vez cada día", "every_hour": "Una vez cada hora", "every_minute": "Una vez cada minuto", "every_second": "Una vez cada segundo", "every_six_hours": "Una vez cada seis horas", + "threads_counter_many": "{{count}} mensajes en hilo sin leer", + "unread_messages_counter_many": "{{count}} mensajes sin leer", "Everyone_can_access_this_channel": "Todos pueden acceder a este canal", "Exact": "Exacto", "Example_payload": "Carga útil de ejemplo", @@ -2122,7 +2125,9 @@ "Impersonate_user_description": "Cuando esta opción esté habilitada, la integración publicará como el usuario que activó la integración", "Import": "Importar", "Import_New_File": "Importar archivo nuevo", + "subscription.callout.description.limitsExceeded_many": "Su espacio de trabajo ha superado los límites <1> {{val, list}} . <3> Administre su suscripción para incrementar los límites.", "Import_requested_successfully": "Importación solicitada correctamente", + "subscription.callout.description.limitsReached_many": "Su espacio de trabajo ha alcanzado los límites <1> {{val, list}} . <3> Administre su suscripción para incrementar los límites.", "Import_Type": "Tipo de importación", "Importer_Archived": "Archivado", "Importer_CSV_Information": "El importador de CSV requiere un formato específico; lee la documentación sobre cómo estructurar tu archivo zip:", @@ -2195,15 +2200,12 @@ "Installation": "Instalación ", "Installed": "Instalada", "Installed_at": "Instalada en", - "mentions_counter_many": "{{count}} menciones", "Instance": "Instancia", "Instances": "Instancias", "Instances_health": "Estado de las instancias", "Instance_Record": "Registro de instancia", - "threads_counter_many": "{{count}} mensajes en hilo sin leer", "Instructions": "Instrucciones", "Instructions_to_your_visitor_fill_the_form_to_send_a_message": "Instrucciones para que el visitante rellene el formulario para enviar un mensaje", - "unread_messages_counter_many": "{{count}} mensajes sin leer", "Insert_Contact_Name": "Insertar nombre del contacto", "Insert_Placeholder": "Insertar marcador de posición", "Install_rocket_chat_on_your_preferred_desktop_platform": "Instale Rocket.Chat en su sistema operativo de preferencia.", @@ -2627,10 +2629,8 @@ "Livechat_offline": "Omnichannel fuera de línea", "Livechat_offline_message_sent": "Mensaje de Livechat fuera de línea enviado", "Livechat_OfflineMessageToChannel_enabled": "Enviar mensajes fuera de línea de Livechat a un canal", - "subscription.callout.description.limitsExceeded_many": "Su espacio de trabajo ha superado los límites <1> {{val, list}} . <3> Administre su suscripción para incrementar los límites.", "Omnichannel_on_hold_chat_resumed": "Reanudación del chat en espera: {{comment}}", "Omnichannel_on_hold_chat_automatically": "El chat se ha reanudado automáticamente desde En espera al recibir un nuevo mensaje de {{guest}}", - "subscription.callout.description.limitsReached_many": "Su espacio de trabajo ha alcanzado los límites <1> {{val, list}} . <3> Administre su suscripción para incrementar los límites.", "Omnichannel_on_hold_chat_resumed_manually": "{{user}} ha reanudado el chat manualmente desde En espera ", "Omnichannel_On_Hold_due_to_inactivity": "El chat se ha puesto automáticamente en espera porque no hemos recibido ninguna respuesta de {{guest}} en {{timeout}} segundos", "Omnichannel_On_Hold_manually": "{{user}} ha puesto el chat en espera manualmente ", diff --git a/packages/i18n/src/locales/fr.i18n.json b/packages/i18n/src/locales/fr.i18n.json index bd809aba9176..ff96989499f8 100644 --- a/packages/i18n/src/locales/fr.i18n.json +++ b/packages/i18n/src/locales/fr.i18n.json @@ -277,6 +277,7 @@ "add-livechat-department-agents_description": "Autorisation d'ajouter des agents omnicanaux aux départements", "add-oauth-service": "Ajouter un service Oauth", "add-oauth-service_description": "Autorisation d'ajouter un nouveau service Oauth", + "Calls_in_queue_many": "{{count}} appels en file d'attente", "add-user": "Ajouter un utilisateur", "add-user_description": "Autorisation d'ajouter de nouveaux utilisateurs au serveur via l'écran des utilisateurs", "add-user-to-any-c-room": "Ajouter un utilisateur à un canal public", @@ -335,7 +336,6 @@ "All_messages": "Tous les messages", "All_users": "Tous les utilisateurs", "All_users_in_the_channel_can_write_new_messages": "Tous les utilisateurs du canal peuvent écrire de nouveaux messages", - "Calls_in_queue_many": "{{count}} appels en file d'attente", "Allow_collect_and_store_HTTP_header_informations": "Autoriser la collecte et le stockage des informations d'en-tête HTTP", "Allow_collect_and_store_HTTP_header_informations_description": "Ce paramètre détermine si Livechat est autorisé à stocker les informations collectées à partir des données d'en-tête HTTP, telles que l'adresse IP, l'agent utilisateur, etc.", "Allow_Invalid_SelfSigned_Certs": "Autoriser les certificats auto-signés invalides", @@ -944,6 +944,7 @@ "Contact_not_found": "Contact introuvable", "Contact_Profile": "Profil de contact", "Contact_Info": "Informations de contact", + "message_counter_many": "{{count}} messages", "Content": "Contenu", "Continue": "Continuer", "Continuous_sound_notifications_for_new_livechat_room": "Notifications sonores continues pour le nouveau salon omnicanal", @@ -958,6 +959,7 @@ "Conversations": "Conversations", "Conversations_per_day": "Conversations par jour", "Convert": "Convertir", + "meteor_status_reconnect_in_many": "nouvelle tentative dans {{count}} secondes...", "Convert_Ascii_Emojis": "Convertir le code ASCII en emoji", "Convert_to_channel": "Convertir en canal", "Converting_channel_to_a_team": "Vous convertissez ce canal en équipe. Tous les membres seront conservés.", @@ -1378,7 +1380,6 @@ "Desktop_Notifications_Duration_Description": "Affichage des notifications de bureau en secondes. Cela peut affecter le centre de notification d'OS X. Entrez 0 pour utiliser les paramètres du navigateur par défaut et ne pas affecter le centre de notifications d'OS X.", "Desktop_Notifications_Enabled": "Les notifications de bureau sont activées", "Desktop_Notifications_Not_Enabled": "Les notifications de bureau ne sont pas activées", - "message_counter_many": "{{count}} messages", "Details": "Détails", "line": "ligne", "Device_Management_IP": "IP", @@ -1397,7 +1398,6 @@ "Direct_Reply_Debug_Description": "[Attention] L'activation du mode de débogage affichera votre mot de passe en texte brut dans la console d'administration.", "Direct_Reply_Delete": "Supprimer les e-mails", "Direct_Reply_Delete_Description": "[Attention] Si cette option est activée, tous les messages non lus sont supprimés définitivement, même ceux qui ne sont pas des réponses directes. La boîte aux lettres configurée est alors toujours vide et ne peut pas être traitée en parallèle par des humains.", - "meteor_status_reconnect_in_many": "nouvelle tentative dans {{count}} secondes...", "Direct_Reply_Enable": "Activer la réponse directe", "Direct_Reply_Enable_Description": "[Attention] Si les réponses directes sont activées, Rocket.Chat contrôle la boîte aux lettres configurée. Tous les e-mails non lus sont récupérés, marqués comme lus et traités. Les réponses directes ne doivent être activées que si la boîte aux lettres utilisée est accessible exclusivement à Rocket.Chat et qu'elle n'est pas lue/traitée en parallèle par des humains.", "Direct_Reply_Frequency": "Fréquence de vérification des e-mails", diff --git a/packages/i18n/src/locales/it.i18n.json b/packages/i18n/src/locales/it.i18n.json index ab446b86dde3..39cce6358b2a 100644 --- a/packages/i18n/src/locales/it.i18n.json +++ b/packages/i18n/src/locales/it.i18n.json @@ -15,9 +15,9 @@ "__username__is_no_longer__role__defined_by__user_by_": "{{username}} non è più {{role}}, da {{user_by}}", "__username__was_set__role__by__user_by_": "A {{username}} è stato assegnato il ruolo di {{role}} da {{user_by}}", "__count__without__department__": "{{count}} senza reparto", - "__usersCount__member_joined_many": "+ {{count}} membri si sono uniti", "__count__without__tags__": "{{count}} senza tag", "__count__without__assignee__": "{{count}} non assegnate", + "__usersCount__member_joined_many": "+ {{count}} membri si sono uniti", "removed__username__as__role_": "ha rimosso {{username}} come {{role}}", "set__username__as__role_": "ha impostato {{username}} come {{role}}", "This_room_encryption_has_been_enabled_by__username_": "La crittografia di questa stanza è stata attivata da {{username}}", @@ -230,8 +230,10 @@ "Accounts_RegistrationForm_Secret_URL": "URL segreto", "Accounts_RegistrationForm_SecretURL": "URL segreto del modulo di registrazione ", "Accounts_RegistrationForm_SecretURL_Description": "È necessario fornire una stringa casuale che verrà aggiunta all'URL di registrazione. Esempio: `https://open.rocket.chat/register/[secret_hash]`", + "Apps_Count_Enabled_many": "{{count}} app abilitate", "Accounts_RequireNameForSignUp": "Richiedi il nome per la registrazione", "Accounts_RequirePasswordConfirmation": "Richiede conferma della password", + "Private_Apps_Count_Enabled_many": "{{count}} applicazioni private abilitate", "Accounts_SearchFields": "Campi da considerare nella ricerca", "Accounts_Send_Email_When_Activating": "Invia mail all'utente quando quando è attivato", "Accounts_Send_Email_When_Deactivating": "Invia mail all'utente quando quando è inattivato", @@ -262,10 +264,8 @@ "Add_Reaction": "Aggiungi reazione", "Add_Role": "Aggiungi ruolo", "Add_Server": "Aggiungi server", - "Apps_Count_Enabled_many": "{{count}} app abilitate", "Add_user": "Aggiungi utente", "Add_User": "Aggiungi utente", - "Private_Apps_Count_Enabled_many": "{{count}} applicazioni private abilitate", "Add_users": "Aggiungi utenti", "add-oauth-service": "Aggiungi servizio Oauth", "add-oauth-service_description": "Autorizzazione ad aggiungere un nuovo servizio Oauth", @@ -714,6 +714,7 @@ "Conversation_finished_message": "Messaggio di conversazione terminato", "conversation_with_s": "la conversazione con %s", "Conversations": "Conversazioni", + "meteor_status_reconnect_in_many": "riprovo tra {{count}} secondi...", "Convert_Ascii_Emojis": "Converti gli ASCII in Emoji", "Converted__roomName__to_team": "ha convertito #{{roomName}} in una squadra", "Converted__roomName__to_channel": "ha convertito #{{roomName}} in un Channel", @@ -1113,7 +1114,6 @@ "Direct_Reply_Debug": "Debug Direct Reply", "Direct_Reply_Debug_Description": "[Attenzione] L'attivazione della modalità di debug mostrerebbe la tua 'password di testo normale' nella Console di amministrazione.", "Direct_Reply_Delete": "Elimina email intercettate", - "meteor_status_reconnect_in_many": "riprovo tra {{count}} secondi...", "Direct_Reply_Enable": "Abilita risposta diretta", "Direct_Reply_Frequency": "Email Controlla frequenza", "Direct_Reply_Frequency_Description": "(in minuti, default / minimo 2)", diff --git a/packages/i18n/src/locales/pa-IN.i18n.json b/packages/i18n/src/locales/pa-IN.i18n.json index 08ba34c215ae..18aa4d8eee0b 100644 --- a/packages/i18n/src/locales/pa-IN.i18n.json +++ b/packages/i18n/src/locales/pa-IN.i18n.json @@ -1,5 +1,6 @@ { "500": "ਅੰਦਰੂਨੀ ਸਰਵਰ ਗੜਬੜ", + "set__username__as__role_": "set {{username}} ਨੂੰ {{role}}", "away": "ਦੂਰ", "Away": "ਦੂਰ", "busy": "ਰੁਝੇਵਾਂ", diff --git a/packages/i18n/src/locales/pl.i18n.json b/packages/i18n/src/locales/pl.i18n.json index f71dad33e584..0936ec845df1 100644 --- a/packages/i18n/src/locales/pl.i18n.json +++ b/packages/i18n/src/locales/pl.i18n.json @@ -297,6 +297,7 @@ "add-oauth-service": "Dodaj usługę Oauth", "add-oauth-service_description": "Uprawnienie do dodawania nowej usługi Oauth", "add-team-channel": "Dodaj zespół Channel", + "Calls_in_queue_many": "{{count}} połączeń w kolejce", "add-team-channel_description": "Zezwolenie na dodanie kanału do zespołu", "add-team-member": "Dodaj członka zespołu", "add-team-member_description": "Uprawnienie do dodawania członków do zespołu", @@ -320,6 +321,7 @@ "Admin_disabled_encryption": "Administrator nie włączył szyfrowania E2E", "Admin_Info": "Informacje administracyjne", "admin-no-active-video-conf-provider": "**Połączenie konferencyjne nie jest włączone**: Skonfiguruj połączenia konferencyjne, aby były dostępne w tej przestrzeni roboczej.", + "Calls_in_queue_few": "{{count}} połączeń w kolejce", "admin-video-conf-provider-not-configured": "**Połączenie konferencyjne nie jest włączone**: Skonfiguruj połączenia konferencyjne, aby były dostępne w tej przestrzeni roboczej.", "admin-no-videoconf-provider-app": "**Połączenie konferencyjne nie jest włączone**: Aplikacje do połączeń konferencyjnych są dostępne w marketplace Rocket.Chat.", "Administration": "Administracja", @@ -365,7 +367,6 @@ "All_status": "Cały status", "All_users": "Wszyscy użytkownicy", "All_users_in_the_channel_can_write_new_messages": "Wszyscy użytkownicy na kanale mogą pisać nowe wiadomości", - "Calls_in_queue_many": "{{count}} połączeń w kolejce", "Allow_collect_and_store_HTTP_header_informations": "Zezwalaj na zbieranie i przechowywanie danych nagłówków HTTP", "Allow_collect_and_store_HTTP_header_informations_description": "To ustawienie określa, czy Livechat może przechowywać informacje zebrane z danych nagłówka HTTP, takie jak adres IP, agent użytkownika itp.", "Allow_Invalid_SelfSigned_Certs": "Zezwalaj na nieprawidłowo samodzielnie podpisane certyfikaty", @@ -394,7 +395,6 @@ "Animals_and_Nature": "Fauna i flora", "Announcement": "Ogłoszenie", "Anonymous": "Anonimowy", - "Calls_in_queue_few": "{{count}} połączeń w kolejce", "Answer_call": "Odbierz połączenie", "API": "API", "API_Add_Personal_Access_Token": "Dodaj nowy osobisty token dostępowy", @@ -1028,6 +1028,7 @@ "Contact_not_found": "Nie znaleziono kontaktu", "Contact_Profile": "Profil kontaktu", "Contact_Info": "Informacje o kontakcie", + "message_counter_many": "{{count}} wiadomości", "Content": "Zawartość", "Continue": "Kontynuuj", "Continuous_sound_notifications_for_new_livechat_room": "Ciągłe powiadomienia dźwiękowe dla nowego pokoju omnichannel", @@ -1044,6 +1045,7 @@ "Conversations": "Rozmowy", "Conversations_per_day": "Rozmowy na dzień", "Convert": "Konwertuj", + "meteor_status_reconnect_in_many": "spróbuj jeszcze raz za {{count}} sekund...", "Convert_Ascii_Emojis": "Konwertuj ASCII na emotikon", "Convert_to_channel": "Konwertuj na kanał", "Converting_channel_to_a_team": "Konwertujesz ten kanał na zespół. Wszyscy członkowie zostaną utrzymani.", @@ -1121,6 +1123,7 @@ "Country_Denmark": "Dania", "Country_Djibouti": "Dżibuti", "Country_Dominica": "Dominika", + "message_counter_few": "{{count}} wiadomości", "Country_Dominican_Republic": "Dominikana", "Country_Ecuador": "Ekwador", "Country_Egypt": "Egipt", @@ -1156,6 +1159,7 @@ "Country_Heard_Island_and_Mcdonald_Islands": "Wyspy Heard i McDonalda", "Country_Holy_See_Vatican_City_State": "Watykan", "Country_Honduras": "Honduras", + "meteor_status_reconnect_in_few": "spróbuj jeszcze raz za {{count}} sekund...", "Country_Hong_Kong": "Hongkong", "Country_Hungary": "Węgry", "Country_Iceland": "Islandia", @@ -1476,7 +1480,6 @@ "Desktop_Notifications_Duration_Description": "Liczba sekund wyświetlania powiadomienia na pulpicie. Może to mieć wpływ na centrum powiadomień systemu OS X. Wprowadź 0, aby użyć domyślnych ustawień przeglądarki i nie wpływać na centrum powiadomień systemu OS X.", "Desktop_Notifications_Enabled": "Powiadomienia na pulpicie są włączone", "Desktop_Notifications_Not_Enabled": "Powiadomienia na pulpicie nie są włączone", - "message_counter_many": "{{count}} wiadomości", "Details": "Szczegóły", "Device_Changes_Not_Available": "Zmiany w urządzeniach niedostępne w tej przeglądarce. Aby uzyskać gwarancję dostępności, skorzystaj z oficjalnej aplikacji desktopowej Rocket.Chat.", "Device_Changes_Not_Available_Insecure_Context": "Zmiany w urządzeniach są dostępne tylko w bezpiecznych kontekstach (np. https://)", @@ -1515,7 +1518,6 @@ "Direct_Reply_Debug_Description": "[Uwaga] Włączenie trybu debugowania wyświetli hasło w formacie tekstowym w konsoli administracyjnej.", "Direct_Reply_Delete": "Usuń wiadomości e-mail", "Direct_Reply_Delete_Description": "[Uwaga!] Jeśli ta opcja jest włączona, wszystkie nieprzeczytane wiadomości są nieodwracalnie usuwane, nawet te, które nie są odpowiedziami bezpośrednimi. Skonfigurowana skrzynka pocztowa jest wtedy zawsze pusta i nie może być przetwarzana „równolegle” przez ludzi.", - "meteor_status_reconnect_in_many": "spróbuj jeszcze raz za {{count}} sekund...", "Direct_Reply_Enable": "Włącz odpowiedź bezpośrednią", "Direct_Reply_Enable_Description": "[Uwaga!] Jeśli włączona jest opcja „Odpowiedź bezpośrednia”, Rocket.Chat będzie kontrolował skonfigurowaną skrzynkę pocztową. Wszystkie nieprzeczytane wiadomości e-mail są pobierane, oznaczane jako przeczytane i przetwarzane. Opcja „Odpowiedź bezpośrednia” powinna być włączona tylko wtedy, gdy do używanej skrzynki pocztowej dostęp ma tylko Rocket.Chat i gdy nie jest ona czytana/przetwarzana „równolegle” przez ludzi.", "Direct_Reply_Frequency": "Częstotliwość sprawdzania poczty e-mail", @@ -1607,7 +1609,6 @@ "Markdown_Marked_Tables": "Włącz oznaczone tablice", "duplicated-account": "Zduplikowane konto", "E2E Encryption": "Szyfrowanie E2E", - "message_counter_few": "{{count}} wiadomości", "Markdown_Parser": "Markdown Parser", "Markdown_SupportSchemesForLink": "Przecena systemy wsparcia dla Łącze", "E2E Encryption_Description": "Zachowaj prywatność rozmów, zapewniając, że tylko nadawca i zamierzeni odbiorcy mogą je przeczytać.", @@ -1655,7 +1656,6 @@ "edit-other-user-active-status_description": "Zezwolenie na włączanie i wyłączanie innych kont", "edit-other-user-avatar": "Edytuj awatar innego użytkownika", "edit-other-user-avatar_description": "Zezwolenie na zmianę awatara innego użytkownika.", - "meteor_status_reconnect_in_few": "spróbuj jeszcze raz za {{count}} sekund...", "edit-other-user-e2ee": "Edytuj szyfrowanie E2E innych użytkowników", "edit-other-user-e2ee_description": "Zezwolenie na modyfikację szyfrowania E2E innego użytkownika.", "edit-other-user-info": "Edytuj inne informacje o użytkowniku", diff --git a/packages/i18n/src/locales/pt-BR.i18n.json b/packages/i18n/src/locales/pt-BR.i18n.json index 146292954d0d..0fecc1fa944a 100644 --- a/packages/i18n/src/locales/pt-BR.i18n.json +++ b/packages/i18n/src/locales/pt-BR.i18n.json @@ -15,9 +15,9 @@ "__username__is_no_longer__role__defined_by__user_by_": "{{username}} não pertence mais a {{role}}, por {{user_by}}", "__username__was_set__role__by__user_by_": "{{username}} foi definido como {{role}} por {{user_by}}", "__count__without__department__": "{{count}} sem departamento", - "__usersCount__member_joined_many": "+ {{count}} membros entraram", "__count__without__tags__": "{{count}} sem tags", "__count__without__assignee__": "{{count}} sem responsável", + "__usersCount__member_joined_many": "+ {{count}} membros entraram", "This_room_encryption_has_been_enabled_by__username_": "A criptografia desta sala foi ativada por {{username}}", "This_room_encryption_has_been_disabled_by__username_": "A criptografia desta sala foi desativada por {{username}}", "Enabled_E2E_Encryption_for_this_room": "Encriptação E2E habilitada para essa sala", @@ -301,6 +301,7 @@ "add-oauth-service": "Adicionar Serviço OAuth", "add-oauth-service_description": "Permissão para adicionar um novo serviço OAuth", "add-team-channel": "Adicionar Time ao Canal", + "Calls_in_queue_many": "{{count}} chamadas na fila", "add-team-channel_description": "Permissão para adicionar um canal a um time", "add-team-member": "Adicionar membro ao Team", "add-team-member_description": "Permissão para adicionar membros ao time", @@ -367,7 +368,6 @@ "All_status": "Todos os estados", "All_users": "Todos os usuários", "All_users_in_the_channel_can_write_new_messages": "Todos usuários no canal podem enviar mensagens novas", - "Calls_in_queue_many": "{{count}} chamadas na fila", "Allow_collect_and_store_HTTP_header_informations": "Permitir coleta e armazenamento de informações do cabeçalho HTTP", "Allow_collect_and_store_HTTP_header_informations_description": "Esta configuração determina se o Livechat tem permissão para armazenar informações coletadas dos dados do cabeçaho HTTP, como endereço IP, agente usuário, etc.", "Allow_Invalid_SelfSigned_Certs": "Permitir certificados autoassinados inválidos", @@ -984,6 +984,7 @@ "Contact_not_found": "Contato não encontrado", "Contact_Profile": "Perfil do contato", "Contact_Info": "Informações do contato", + "message_counter_many": "{{count}} mensagens", "Content": "Conteúdo", "Continue": "Continuar", "Continuous_sound_notifications_for_new_livechat_room": "Notificações sonoras contínuas para nova sala de omnichannel", @@ -999,6 +1000,7 @@ "Conversations": "Conversas", "Conversations_per_day": "Conversas por dia", "Convert": "Converter", + "meteor_status_reconnect_in_many": "tentando novamente em {{count}} segundos...", "Convert_Ascii_Emojis": "Converter ASCII em emoji", "Convert_to_channel": "Converter em canal", "Converting_channel_to_a_team": "Você está convertendo este canal em uma equipe. Todos os membros serão mantidos.", @@ -1416,7 +1418,6 @@ "Desktop_Notifications_Duration_Description": "Segundos para exibir a notificação da área de trabalho. Isso poderá afetar o Centro de notificação do OS X. Insira 0 para usar as configurações padrão do navegador e não afetar o Centro de notificação do OS X.", "Desktop_Notifications_Enabled": "Notificações da área de trabalho estão habilitadas", "Desktop_Notifications_Not_Enabled": "Notificações da área de trabalho estão desabilitadas", - "message_counter_many": "{{count}} mensagens", "Details": "Detalhes", "Device_Changes_Not_Available": "Mudanças de dispositivo não estão disponíveis neste navegador, para disponíbilidade garantida, use o aplicativo desktop oficial do Rocket.Chat.", "Device_Changes_Not_Available_Insecure_Context": "Mudanças de dispositivo somente estão disponíveis em contextos seguros. (https://)", @@ -1437,7 +1438,6 @@ "Direct_Reply_Debug_Description": "[Cuidado] A ativação do modo de depuração exibirá sua \"Senha de texto simples\" no console do administrador.", "Direct_Reply_Delete": "Excluir e-mails", "Direct_Reply_Delete_Description": "[Atenção!] Se esta opção estiver ativada, todas as mensagens não lidas serão irrevogavelmente excluídas, mesmo aquelas que não sejam respostas diretas. A caixa de entrada de e-mail configurada fica sempre vazia e não pode ser processada \"paralelamente\" por pessoas.", - "meteor_status_reconnect_in_many": "tentando novamente em {{count}} segundos...", "Direct_Reply_Enable": "Ativar resposta direta", "Direct_Reply_Enable_Description": "[Atenção!] Se \"Resposta direta\" estiver habilitado, o Rocket.Chat vai controlar a caixa de entrada de e-mail. Todos os e-mails não lidos serão recuperados, marcados como lidos e processados. \"Resposta direta\" deve ser ativado apenas se a caixa de entrada for destinada exclusivamente para acesso do Rocket.Chat e não lida/processada \"em paralelo\" por humanos.", "Direct_Reply_Frequency": "Frequência de verificação de e-mail", @@ -5014,4 +5014,4 @@ "Enterprise": "Enterprise", "UpgradeToGetMore_engagement-dashboard_Title": "Analytics", "UpgradeToGetMore_auditing_Title": "Auditoria de mensagem" -} +} \ No newline at end of file diff --git a/packages/i18n/src/locales/ru.i18n.json b/packages/i18n/src/locales/ru.i18n.json index 774f895dc33a..9b4b31910ba4 100644 --- a/packages/i18n/src/locales/ru.i18n.json +++ b/packages/i18n/src/locales/ru.i18n.json @@ -239,8 +239,10 @@ "Accounts_RegistrationForm_Secret_URL": "Секретный URL-адрес", "Accounts_RegistrationForm_SecretURL": "Секретный URL-адрес регистрационной формы", "Accounts_RegistrationForm_SecretURL_Description": "Вы должны предоставить случайную строку, которая будет добавлена к вашему регистрационному URL-адресу. Например: `https://open.rocket.chat/register/[secret_hash]`", + "Apps_Count_Enabled_many": "{{count}} приложений(-я) включено", "Accounts_RequireNameForSignUp": "Требуется имя для регистрации", "Accounts_RequirePasswordConfirmation": "Запрашивать подтверждение пароля", + "Private_Apps_Count_Enabled_many": "{{count}} приватных приложений включено", "Accounts_RoomAvatarExternalProviderUrl": "URL внешнего поставщика аватаров", "Accounts_RoomAvatarExternalProviderUrl_Description": "Пример: `https://acme.com/api/v1/{roomId}`", "Accounts_SearchFields": "Поля, которые следует учитывать при поиске", @@ -296,10 +298,8 @@ "Add_Sender_To_ReplyTo": "Добавить отправителя в ответ", "Add_Server": "Добавить Сервер", "Add_URL": "Добавить URL", - "Apps_Count_Enabled_many": "{{count}} приложений(-я) включено", "Add_user": "Добавить пользователя", "Add_User": "Добавить Пользователя", - "Private_Apps_Count_Enabled_many": "{{count}} приватных приложений включено", "Add_users": "Добавить пользователей", "Add_members": "Добавить участников", "add-all-to-room": "Добавить всех пользователей в чат", @@ -311,6 +311,7 @@ "bypass-time-limit-edit-and-delete": "Обход ограничения по времени", "bypass-time-limit-edit-and-delete_description": "Разрешение на обход ограничения по времени для редактирования и удаления сообщений", "add-team-channel": "Добавить Channel Команды", + "Calls_in_queue_many": "{{count}} Звонков в очереди", "add-team-channel_description": "Разрешение на добавление канала в Команду", "add-team-member": "Добавить участника Команды", "add-team-member_description": "Разрешение на добавление участников в Команду", @@ -336,6 +337,7 @@ "Admin_disabled_encryption": "Ваш администратор не включил шифрование E2E.", "Admin_Info": "Информация Администратора", "admin-no-active-video-conf-provider": "**Функция звонков не включена**: Настройте звонки, чтобы сделать их доступными для вашего сервера.", + "Calls_in_queue_few": "{{count}} Звонков в очереди", "admin-video-conf-provider-not-configured": "**Функция звонков не включена**: Настройте звонки, чтобы сделать их доступными для вашего сервера.", "admin-no-videoconf-provider-app": "**Функция звонков не включена**: Приложения для звонков могут быть установлены из магазина приложений Rocket.Chat администратором сервера.", "Administration": "Администрирование", @@ -361,12 +363,14 @@ "Alias_Set": "Настройки псевдонима", "AutoLinker_Email": "AutoLinker Email", "Aliases": "Псевдонимы", + "Apps_Count_Enabled_few": "{{count}} приложений(-я) включено", "AutoLinker_Phone": "Подсвечивать телефоны", "AutoLinker_Phone_Description": "Автоматически выделять телефонные номера, например `(123)456-7890`", "All": "Все", "AutoLinker_StripPrefix": "Удаление префиксов", "All_Apps": "Все приложения", "AutoLinker_StripPrefix_Description": "Сокращать формат, например: https://rocket.chat => rocket.chat", + "Private_Apps_Count_Enabled_few": "{{count}} приватных приложений включено", "All_added_tokens_will_be_required_by_the_user": "Все добавленные токены потребуются пользователем", "All_categories": "Все категории", "AutoLinker_Urls_Scheme": "AutoLinker Scheme:// URLs", @@ -381,7 +385,6 @@ "All_status": "Все статусы", "All_users": "Все пользователи", "All_users_in_the_channel_can_write_new_messages": "Все пользователи на канале могут писать новые сообщения", - "Calls_in_queue_many": "{{count}} Звонков в очереди", "Allow_collect_and_store_HTTP_header_informations": "Разрешить собирать и хранить информацию заголовка HTTP", "Allow_collect_and_store_HTTP_header_informations_description": "Этот параметр определяет, разрешено ли Livechat хранить информацию, собранную из данных заголовка HTTP, таких как IP-адрес, User-Agent и т. Д.", "Allow_Invalid_SelfSigned_Certs": "Разрешить недействительные самоподписанные сертификаты", @@ -390,14 +393,12 @@ "Allow_Online_Agents_Outside_Business_Hours": "Разрешить агентов в сети вне рабочих часов", "Allow_Online_Agents_Outside_Office_Hours": "Разрешить агентов в сети вне рабочего времени", "Allow_Save_Media_to_Gallery": "Разрешить сохранять медиа данные в галерее", - "Apps_Count_Enabled_few": "{{count}} приложений(-я) включено", "Allow_switching_departments": "Разрешить посетителю сменить отдел", "Almost_done": "Почти сделано", "Alphabetical": "По алфавиту", "bold": "жирный", "Also_send_thread_message_to_channel_behavior": "Поведение Также отправить сообщение треда в чат", "Also_send_to_channel": "Также отправить в чат", - "Private_Apps_Count_Enabled_few": "{{count}} приватных приложений включено", "Always_open_in_new_window": "Всегда открывать в новом окне", "Analytics": "Аналитика", "Analytics_Description": "Посмотрите, как пользователи взаимодействуют с вашим рабочим пространством.", @@ -412,7 +413,6 @@ "Animals_and_Nature": "Животные и природа", "Announcement": "Объявление", "Anonymous": "Аноним", - "Calls_in_queue_few": "{{count}} Звонков в очереди", "Answer_call": "Ответить на вызов", "API": "API", "API_Add_Personal_Access_Token": "Добавить токен личного доступа", @@ -1053,6 +1053,7 @@ "Contact_not_found": "Контакт не найден", "Contact_Profile": "Профиль контакта", "Contact_Info": "Контактная информация", + "message_counter_many": "{{count}} сообщения", "Content": "Содержимое", "Continue": "Продолжить", "Continuous_sound_notifications_for_new_livechat_room": "Непрерывные звуковые уведомления для новой комнаты livechat", @@ -1067,6 +1068,7 @@ "Conversations": "Сеансы чата", "Conversations_per_day": "Сеансы чата за день", "Convert": "Конвертировать", + "meteor_status_reconnect_in_many": "пытается снова через {{count}} секунд ...", "Convert_Ascii_Emojis": "Конвертировать ASCII в эмодзи", "Convert_to_channel": "Конвертировать в чат", "Converting_channel_to_a_team": "Вы преобразуете этот чат в Команду. Все его участники будут сохранены.", @@ -1142,6 +1144,7 @@ "Country_Denmark": "Дания", "Country_Djibouti": "Джибути", "Country_Dominica": "Доминика", + "message_counter_few": "{{count}} сообщения", "Country_Dominican_Republic": "Доминиканская Республика", "Country_Ecuador": "Эквадор", "Country_Egypt": "Египет", @@ -1177,6 +1180,7 @@ "Country_Heard_Island_and_Mcdonald_Islands": "Острова Херд и Макдональд", "Country_Holy_See_Vatican_City_State": "Святейший Престол (Государство Ватикан)", "Country_Honduras": "Гондурас", + "meteor_status_reconnect_in_few": "пытается снова через {{count}} секунд ...", "Country_Hong_Kong": "Гонконг", "Country_Hungary": "Венгрия", "Country_Iceland": "Исландия", @@ -1489,7 +1493,6 @@ "Desktop_Notifications_Enabled": "Уведомления на компьютере включены", "Desktop_Notifications_Not_Enabled": "Уведомления на рабочем столе не включены", "Unselected_by_default": "Выбрано не по умолчанию", - "message_counter_many": "{{count}} сообщения", "Details": "Подробности", "Device_Management": "Управление устройствами", "Device_Management_Client": "Клиент", @@ -1526,7 +1529,6 @@ "Direct_Reply_Debug_Description": "[ВНИМАНИЕ] Режим отладки будет отображать ваш пароль в открытом виде в консоли администратора", "Direct_Reply_Delete": "Удалить перехваченную электронную почту", "Direct_Reply_Delete_Description": "[Внимание!] Если эта опция включена; все непрочитанные сообщения, даже те - что не являются прямыми ответами - безвозвратно удаляться. Настроенный e-mail ящик будет постоянно пустым и не сможет быть обработан \"параллельно\" людьми.", - "meteor_status_reconnect_in_many": "пытается снова через {{count}} секунд ...", "Direct_Reply_Enable": "Разрешить прямой ответ", "Direct_Reply_Enable_Description": "[Внимание!] Если \"Прямой ответ\" включен; Rocket.Chat будет управлять настроенным e-mail ящиком. Все непрочитанные сообщения будут получены, помечены как прочитаны и обработаны. \"Прямой ответ\" должен быть активирован только при условии что все письма отправленные в ящик предполагают обработку Rocket.Chat-ом без \"параллельного\" участия людей в обработке писем.", "Direct_Reply_Frequency": "Частота проверки почты", @@ -1616,7 +1618,6 @@ "Markdown_Marked_Tables": "Enable Marked Tables", "duplicated-account": "Дублированный аккаунт", "E2E Encryption": "Шифрование E2E", - "message_counter_few": "{{count}} сообщения", "Markdown_Parser": "Парсер Markdown", "Markdown_SupportSchemesForLink": "Поддерживать Markdown систему ссылок", "Markdown_SupportSchemesForLink_Description": "Разрешённые Markdown системы через запятую", @@ -1661,7 +1662,6 @@ "edit-other-user-active-status_description": "Разрешение на блокировку и разблокировку аккаунтов", "edit-other-user-avatar": "Редактировать Аватар другого пользователя", "edit-other-user-avatar_description": "Разрешение на изменение аватара другого пользователя.", - "meteor_status_reconnect_in_few": "пытается снова через {{count}} секунд ...", "edit-other-user-e2ee": "Редактировать E2E шифрование других пользователей", "edit-other-user-e2ee_description": "Разрешение на изменение E2E шифрования другого пользователя.", "edit-other-user-info": "Редактировать информацию другого пользователя", diff --git a/packages/i18n/src/locales/sv.i18n.json b/packages/i18n/src/locales/sv.i18n.json index b6192f7084fd..bea0ea1cb238 100644 --- a/packages/i18n/src/locales/sv.i18n.json +++ b/packages/i18n/src/locales/sv.i18n.json @@ -1575,7 +1575,7 @@ "Direct": "Direkt", "Direction": "Riktning", "Livechat_Facebook_API_Secret": "OmniChannel API-hemlighet", - "Direct_Message": "Direktmeddelande", + "Direct_Message": "Direkt meddelande", "Livechat_Facebook_Enabled": "Facebook integration aktiverad", "Direct_message_creation_description": "Du håller på att skapa en chatt för flera användare. Lägg till de användare du vill prata med via direktmeddelanden på samma plats.", "Direct_message_someone": "Skicka direktmeddelande till någon", @@ -2275,6 +2275,7 @@ "Format": "Format", "Forward": "Vidarebefodra", "Forward_chat": "Vidarebefodra chatt", + "Forward_message": "Direkt meddelande", "Forward_to_department": "Vidarebefodra till avdelning", "Forward_to_user": "Vidarebefodra till användare", "Forwarding": "Vidarebefordran", @@ -3405,6 +3406,7 @@ "Monitors": "Övervakare", "Monthly_Active_Users": "Aktiva användare per månad", "More": "Mer", + "More_actions": "Fler alternativ", "More_channels": "Fler kanaler", "More_direct_messages": "Fler direktmeddelanden", "More_groups": "Fler privata grupper", @@ -5020,6 +5022,7 @@ "Uploads": "Uppladdningar", "Upload_private_app": "Ladda upp en privat app", "Upload_file_description": "Filbeskrivning", + "Upload_file": "Ladda upp fil", "Upload_file_name": "Filnamn", "Upload_file_question": "Ladda upp fil?", "Upload_Folder_Path": "Ladda upp mappväg", diff --git a/packages/i18n/src/locales/uk.i18n.json b/packages/i18n/src/locales/uk.i18n.json index 025504e65891..7cf127f8c8bf 100644 --- a/packages/i18n/src/locales/uk.i18n.json +++ b/packages/i18n/src/locales/uk.i18n.json @@ -700,6 +700,7 @@ "Consulting": "Консалтинг", "Contact": "Контакти", "Contains_Security_Fixes": "Містять виправлення безпеки", + "message_counter_many": "{{count}} повідомлень", "Content": "Вміст", "Continue": "Продовжити", "Continuous_sound_notifications_for_new_livechat_room": "Постійні звукові сповіщення для нової livechat кімнати", @@ -781,6 +782,7 @@ "Country_Denmark": "Данія", "Country_Djibouti": "Джибуті", "Country_Dominica": "Домініка", + "message_counter_few": "{{count}} повідомлень", "Country_Dominican_Republic": "Домініканська республіка", "Country_Ecuador": "Еквадор", "Country_Egypt": "Єгипет", @@ -1095,7 +1097,6 @@ "Desktop_Notifications_Duration_Description": "Час у секундах для відображення сповіщень на робочому столі. Може вплинути на Центр сповіщень операційної стистеми. Введіть 0, щоб використовувати настройки браузера за замовчуванням і не впливати на на Центр сповіщень операційної стистеми", "Desktop_Notifications_Enabled": "Сповіщення на робочому столі ввімкнені", "Desktop_Notifications_Not_Enabled": "Сповіщення на робочому столі вимкені", - "message_counter_many": "{{count}} повідомлень", "Details": "Деталі", "line": "лінія", "Different_Style_For_User_Mentions": "Різний стиль для згадування користувачів", @@ -1185,7 +1186,6 @@ "Markdown_Marked_Tables": "Увімкнути позначені таблиці", "duplicated-account": "Дублювання облікового запису", "E2E Encryption": "Шифрування E2E", - "message_counter_few": "{{count}} повідомлень", "Markdown_Parser": "Аналізатор зі зниженням курсу", "Markdown_SupportSchemesForLink": "Markdown Схеми підтримки для Link", "Markdown_SupportSchemesForLink_Description": "Розділених комами список дозволених схем", diff --git a/packages/instance-status/CHANGELOG.md b/packages/instance-status/CHANGELOG.md index 968ac7af7959..ef804a060a70 100644 --- a/packages/instance-status/CHANGELOG.md +++ b/packages/instance-status/CHANGELOG.md @@ -1,5 +1,41 @@ # @rocket.chat/instance-status +## 0.0.39 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/models@0.0.39 +
+ +## 0.0.39-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/models@0.0.39-rc.2 +
+ +## 0.0.39-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/models@0.0.39-rc.1 +
+ +## 0.0.39-rc.0 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/models@0.0.39-rc.0 +
+ ## 0.0.38 ### Patch Changes diff --git a/packages/instance-status/package.json b/packages/instance-status/package.json index a6998bbd4c32..1b9a81c6f432 100644 --- a/packages/instance-status/package.json +++ b/packages/instance-status/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/instance-status", - "version": "0.0.38", + "version": "0.0.39", "private": true, "devDependencies": { "@rocket.chat/eslint-config": "workspace:^", diff --git a/packages/livechat/CHANGELOG.md b/packages/livechat/CHANGELOG.md index 8541e820f1bb..05f50031910d 100644 --- a/packages/livechat/CHANGELOG.md +++ b/packages/livechat/CHANGELOG.md @@ -1,5 +1,51 @@ # @rocket.chat/livechat Change Log +## 1.17.0 + +### Minor Changes + +- ([#32233](https://github.com/RocketChat/Rocket.Chat/pull/32233)) Makes the triggers fired by the condition `after-guest-registration` persist on the livechat client, it will persist through reloads and pagination, only reseting when a conversation is closed (no changes were done on the agent side of the conversation) + +### Patch Changes + +-
Updated dependencies [ee5cdfc367]: + + - @rocket.chat/ui-kit@0.34.0 + - @rocket.chat/gazzodown@7.0.0 +
+ +## 1.17.0-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/gazzodown@7.0.0-rc.2 +
+ +## 1.17.0-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/gazzodown@7.0.0-rc.1 +
+ +## 1.17.0-rc.0 + +### Minor Changes + +- ([#32233](https://github.com/RocketChat/Rocket.Chat/pull/32233)) Makes the triggers fired by the condition `after-guest-registration` persist on the livechat client, it will persist through reloads and pagination, only reseting when a conversation is closed (no changes were done on the agent side of the conversation) + +### Patch Changes + +-
Updated dependencies [ee5cdfc367]: + + - @rocket.chat/ui-kit@0.34.0-rc.0 + - @rocket.chat/gazzodown@7.0.0-rc.0 +
+ ## 1.16.0 ### Patch Changes diff --git a/packages/livechat/package.json b/packages/livechat/package.json index 6d1b805b59ab..a47edd10bfce 100644 --- a/packages/livechat/package.json +++ b/packages/livechat/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/livechat", - "version": "1.16.0", + "version": "1.17.0", "files": [ "/build" ], diff --git a/packages/mock-providers/CHANGELOG.md b/packages/mock-providers/CHANGELOG.md index 13e9fd464c72..b399a60c8478 100644 --- a/packages/mock-providers/CHANGELOG.md +++ b/packages/mock-providers/CHANGELOG.md @@ -1,5 +1,23 @@ # @rocket.chat/mock-providers +## 0.0.7 + +### Patch Changes + +-
Updated dependencies [ff4e396416, bc50dd54a2, 70ab2a7b7b]: + + - @rocket.chat/i18n@0.4.0 +
+ +## 0.0.7-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, bc50dd54a2, 70ab2a7b7b]: + + - @rocket.chat/i18n@0.4.0-rc.0 +
+ ## 0.0.6 ### Patch Changes diff --git a/packages/mock-providers/package.json b/packages/mock-providers/package.json index 89208cafaf41..7b3fdbf5dc35 100644 --- a/packages/mock-providers/package.json +++ b/packages/mock-providers/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/mock-providers", - "version": "0.0.6", + "version": "0.0.7", "private": true, "dependencies": { "@rocket.chat/i18n": "workspace:~", diff --git a/packages/model-typings/CHANGELOG.md b/packages/model-typings/CHANGELOG.md index a4ff3abbd66d..be6af1a7d7de 100644 --- a/packages/model-typings/CHANGELOG.md +++ b/packages/model-typings/CHANGELOG.md @@ -1,5 +1,41 @@ # @rocket.chat/model-typings +## 0.4.1 + +### Patch Changes + +-
Updated dependencies [ff4e396416, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 +
+ +## 0.4.1-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 +
+ +## 0.4.1-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 +
+ +## 0.4.1-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 +
+ ## 0.4.0 ### Minor Changes diff --git a/packages/model-typings/package.json b/packages/model-typings/package.json index 5c14dc6b7bb4..dac38893963a 100644 --- a/packages/model-typings/package.json +++ b/packages/model-typings/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/model-typings", - "version": "0.4.0", + "version": "0.4.1", "private": true, "devDependencies": { "@types/jest": "~29.5.7", diff --git a/packages/model-typings/src/models/IBaseModel.ts b/packages/model-typings/src/models/IBaseModel.ts index 36f34a008508..fa053fef9ec8 100644 --- a/packages/model-typings/src/models/IBaseModel.ts +++ b/packages/model-typings/src/models/IBaseModel.ts @@ -85,6 +85,8 @@ export interface IBaseModel< removeById(_id: T['_id']): Promise; + removeByIds(ids: T['_id'][]): Promise; + deleteOne(filter: Filter, options?: DeleteOptions & { bypassDocumentValidation?: boolean }): Promise; deleteMany(filter: Filter, options?: DeleteOptions): Promise; diff --git a/packages/model-typings/src/models/IEmailInboxModel.ts b/packages/model-typings/src/models/IEmailInboxModel.ts index 1bb235848535..93145041af74 100644 --- a/packages/model-typings/src/models/IEmailInboxModel.ts +++ b/packages/model-typings/src/models/IEmailInboxModel.ts @@ -1,8 +1,12 @@ import type { IEmailInbox } from '@rocket.chat/core-typings'; +import type { FindCursor, InsertOneResult, ModifyResult, UpdateFilter } from 'mongodb'; import type { IBaseModel } from './IBaseModel'; -// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface IEmailInboxModel extends IBaseModel { - // + setDisabledById(id: IEmailInbox['_id']): Promise>; + create(emailInbox: Omit): Promise>; + updateById(id: IEmailInbox['_id'], data: UpdateFilter): Promise>>; + findActive(): FindCursor; + findByEmail(email: IEmailInbox['email']): Promise; } diff --git a/packages/model-typings/src/models/IIntegrationHistoryModel.ts b/packages/model-typings/src/models/IIntegrationHistoryModel.ts index 86765893dd53..378142e7519a 100644 --- a/packages/model-typings/src/models/IIntegrationHistoryModel.ts +++ b/packages/model-typings/src/models/IIntegrationHistoryModel.ts @@ -1,9 +1,15 @@ import type { IIntegrationHistory } from '@rocket.chat/core-typings'; +import type { FindOneAndUpdateOptions, InsertOneResult } from 'mongodb'; import type { IBaseModel } from './IBaseModel'; export interface IIntegrationHistoryModel extends IBaseModel { removeByIntegrationId(integrationId: string): ReturnType['deleteMany']>; - findOneByIntegrationIdAndHistoryId(integrationId: string, historyId: string): Promise; + create(integrationHistory: IIntegrationHistory): Promise>; + updateById( + _id: IIntegrationHistory['_id'], + data: Partial, + options?: FindOneAndUpdateOptions, + ): Promise; } diff --git a/packages/model-typings/src/models/ILivechatDepartmentAgentsModel.ts b/packages/model-typings/src/models/ILivechatDepartmentAgentsModel.ts index dfc2dfc5d1f2..45709dc7ff37 100644 --- a/packages/model-typings/src/models/ILivechatDepartmentAgentsModel.ts +++ b/packages/model-typings/src/models/ILivechatDepartmentAgentsModel.ts @@ -67,33 +67,34 @@ export interface ILivechatDepartmentAgentsModel extends IBaseModel, ): Promise; findOneByAgentIdAndDepartmentId(agentId: string, departmentId: string): Promise; - saveAgent(agent: { - agentId: string; - departmentId: string; - username: string; - departmentEnabled: boolean; - count: number; - order: number; - }): Promise; - removeByAgentId(agentId: string): Promise; + saveAgent(agent: Omit): Promise; + removeByAgentId(agentId: string): Promise; removeByDepartmentIdAndAgentId(departmentId: string, agentId: string): Promise; getNextAgentForDepartment( - departmentId: string, + departmentId: ILivechatDepartmentAgents['departmentId'], isLivechatEnabledWhenAgentIdle?: boolean, - ignoreAgentId?: string, + ignoreAgentId?: ILivechatDepartmentAgents['agentId'], extraQuery?: Filter, - ): Promise<{ agentId: string; username: string } | null | undefined>; + ): Promise | null | undefined>; checkOnlineForDepartment(departmentId: string): Promise; getOnlineForDepartment( departmentId: string, isLivechatEnabledWhenAgentIdle?: boolean, ): Promise | undefined>; getBotsForDepartment(departmentId: string): Promise>; - getNextBotForDepartment(departmentId: string, ignoreAgentId?: string): Promise<{ agentId: string; username: string } | undefined>; + getNextBotForDepartment( + departmentId: ILivechatDepartmentAgents['departmentId'], + ignoreAgentId?: ILivechatDepartmentAgents['agentId'], + ): Promise | null | undefined>; replaceUsernameOfAgentByUserId(userId: string, username: string): Promise; countByDepartmentId(departmentId: string): Promise; disableAgentsByDepartmentId(departmentId: string): Promise; enableAgentsByDepartmentId(departmentId: string): Promise; findAllAgentsConnectedToListOfDepartments(departmentIds: string[]): Promise; findByAgentIds(agentIds: string[], options?: FindOptions): FindCursor; + findByAgentsAndDepartmentId( + agentsIds: ILivechatDepartmentAgents['agentId'][], + departmentId: ILivechatDepartmentAgents['departmentId'], + options?: FindOptions, + ): FindCursor; } diff --git a/packages/models/CHANGELOG.md b/packages/models/CHANGELOG.md index 5479e14a00bd..02e520ef1e9b 100644 --- a/packages/models/CHANGELOG.md +++ b/packages/models/CHANGELOG.md @@ -1,5 +1,41 @@ # @rocket.chat/models +## 0.0.39 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/model-typings@0.4.1 +
+ +## 0.0.39-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/model-typings@0.4.1-rc.2 +
+ +## 0.0.39-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/model-typings@0.4.1-rc.1 +
+ +## 0.0.39-rc.0 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/model-typings@0.4.1-rc.0 +
+ ## 0.0.38 ### Patch Changes diff --git a/packages/models/package.json b/packages/models/package.json index e8d4c77158fc..7280cb2e36d8 100644 --- a/packages/models/package.json +++ b/packages/models/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/models", - "version": "0.0.38", + "version": "0.0.39", "private": true, "devDependencies": { "@swc/core": "^1.3.95", diff --git a/packages/rest-typings/CHANGELOG.md b/packages/rest-typings/CHANGELOG.md index 4f2819a3d71c..b2f584d33557 100644 --- a/packages/rest-typings/CHANGELOG.md +++ b/packages/rest-typings/CHANGELOG.md @@ -1,5 +1,51 @@ # @rocket.chat/rest-typings +## 6.9.0 + +### Minor Changes + +- ([#32364](https://github.com/RocketChat/Rocket.Chat/pull/32364)) Fixed issue with "Export room as file" feature (`rooms.export` endpoint) generating an empty export when given an invalid date + +### Patch Changes + +-
Updated dependencies [ff4e396416, ee5cdfc367, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/ui-kit@0.34.0 +
+ +## 6.9.0-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 +
+ +## 6.9.0-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 +
+ +## 6.9.0-rc.0 + +### Minor Changes + +- ([#32364](https://github.com/RocketChat/Rocket.Chat/pull/32364)) Fixed issue with "Export room as file" feature (`rooms.export` endpoint) generating an empty export when given an invalid date + +### Patch Changes + +-
Updated dependencies [ff4e396416, ee5cdfc367, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/ui-kit@0.34.0-rc.0 +
+ ## 6.8.0 ### Minor Changes diff --git a/packages/rest-typings/package.json b/packages/rest-typings/package.json index cd3c10d6ebb4..2d567eb10fab 100644 --- a/packages/rest-typings/package.json +++ b/packages/rest-typings/package.json @@ -1,7 +1,6 @@ { "name": "@rocket.chat/rest-typings", - "private": true, - "version": "6.9.0-develop", + "version": "6.10.0-develop", "devDependencies": { "@rocket.chat/eslint-config": "workspace:^", "@types/jest": "~29.5.7", diff --git a/packages/ui-avatar/CHANGELOG.md b/packages/ui-avatar/CHANGELOG.md index 5a6023b53c47..0d61eb6eb359 100644 --- a/packages/ui-avatar/CHANGELOG.md +++ b/packages/ui-avatar/CHANGELOG.md @@ -1,5 +1,41 @@ # @rocket.chat/ui-avatar +## 3.0.0 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/ui-contexts@7.0.0 +
+ +## 3.0.0-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/ui-contexts@7.0.0-rc.2 +
+ +## 3.0.0-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/ui-contexts@7.0.0-rc.1 +
+ +## 3.0.0-rc.0 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/ui-contexts@7.0.0-rc.0 +
+ ## 2.0.0 ### Patch Changes diff --git a/packages/ui-avatar/package.json b/packages/ui-avatar/package.json index 949dbda74fb5..a5300bc5648a 100644 --- a/packages/ui-avatar/package.json +++ b/packages/ui-avatar/package.json @@ -1,10 +1,10 @@ { "name": "@rocket.chat/ui-avatar", - "version": "2.0.0", + "version": "3.0.0", "private": true, "devDependencies": { "@babel/core": "~7.22.20", - "@rocket.chat/fuselage": "^0.53.7", + "@rocket.chat/fuselage": "^0.54.2", "@rocket.chat/ui-contexts": "workspace:^", "@types/babel__core": "~7.20.3", "@types/react": "~17.0.69", @@ -31,7 +31,7 @@ ], "peerDependencies": { "@rocket.chat/fuselage": "*", - "@rocket.chat/ui-contexts": "6.0.0", + "@rocket.chat/ui-contexts": "7.0.0", "react": "~17.0.2" }, "volta": { diff --git a/packages/ui-client/CHANGELOG.md b/packages/ui-client/CHANGELOG.md index 4ef42e89b343..5f68202e7cb0 100644 --- a/packages/ui-client/CHANGELOG.md +++ b/packages/ui-client/CHANGELOG.md @@ -1,5 +1,41 @@ # @rocket.chat/ui-client +## 7.0.0 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/ui-contexts@7.0.0 +
+ +## 7.0.0-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/ui-contexts@7.0.0-rc.2 +
+ +## 7.0.0-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/ui-contexts@7.0.0-rc.1 +
+ +## 7.0.0-rc.0 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/ui-contexts@7.0.0-rc.0 +
+ ## 6.0.0 ### Patch Changes diff --git a/packages/ui-client/package.json b/packages/ui-client/package.json index 1695860ee949..6b6429df099c 100644 --- a/packages/ui-client/package.json +++ b/packages/ui-client/package.json @@ -1,14 +1,14 @@ { "name": "@rocket.chat/ui-client", - "version": "6.0.0", + "version": "7.0.0", "private": true, "devDependencies": { "@babel/core": "~7.22.20", "@react-aria/toolbar": "^3.0.0-beta.1", "@rocket.chat/css-in-js": "~0.31.25", - "@rocket.chat/fuselage": "^0.53.7", + "@rocket.chat/fuselage": "^0.54.2", "@rocket.chat/fuselage-hooks": "^0.33.1", - "@rocket.chat/icons": "^0.35.0", + "@rocket.chat/icons": "^0.36.0", "@rocket.chat/mock-providers": "workspace:^", "@rocket.chat/ui-contexts": "workspace:~", "@storybook/addon-actions": "~6.5.16", @@ -63,7 +63,7 @@ "@rocket.chat/fuselage": "*", "@rocket.chat/fuselage-hooks": "*", "@rocket.chat/icons": "*", - "@rocket.chat/ui-contexts": "6.0.0", + "@rocket.chat/ui-contexts": "7.0.0", "react": "~17.0.2" }, "volta": { diff --git a/packages/ui-composer/package.json b/packages/ui-composer/package.json index 53998ec80e07..e256334c3eb4 100644 --- a/packages/ui-composer/package.json +++ b/packages/ui-composer/package.json @@ -6,8 +6,8 @@ "@babel/core": "~7.22.20", "@react-aria/toolbar": "^3.0.0-beta.1", "@rocket.chat/eslint-config": "workspace:^", - "@rocket.chat/fuselage": "^0.53.7", - "@rocket.chat/icons": "^0.35.0", + "@rocket.chat/fuselage": "^0.54.2", + "@rocket.chat/icons": "^0.36.0", "@storybook/addon-actions": "~6.5.16", "@storybook/addon-docs": "~6.5.16", "@storybook/addon-essentials": "~6.5.16", diff --git a/packages/ui-contexts/CHANGELOG.md b/packages/ui-contexts/CHANGELOG.md index b8c3a1ca3fbc..622a99d4d898 100644 --- a/packages/ui-contexts/CHANGELOG.md +++ b/packages/ui-contexts/CHANGELOG.md @@ -1,5 +1,51 @@ # @rocket.chat/ui-contexts +## 7.0.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, bc50dd54a2, f83bd56cc5, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0 + - @rocket.chat/i18n@0.4.0 + - @rocket.chat/rest-typings@6.9.0 + - @rocket.chat/ddp-client@0.2.24 +
+ +## 7.0.0-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.2 + - @rocket.chat/rest-typings@6.9.0-rc.2 + - @rocket.chat/ddp-client@0.2.24-rc.2 +
+ +## 7.0.0-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/core-typings@6.9.0-rc.1 + - @rocket.chat/rest-typings@6.9.0-rc.1 + - @rocket.chat/ddp-client@0.2.24-rc.1 +
+ +## 7.0.0-rc.0 + +### Patch Changes + +-
Updated dependencies [ff4e396416, bc50dd54a2, f83bd56cc5, 70ab2a7b7b]: + + - @rocket.chat/core-typings@6.9.0-rc.0 + - @rocket.chat/i18n@0.4.0-rc.0 + - @rocket.chat/rest-typings@6.9.0-rc.0 + - @rocket.chat/ddp-client@0.2.24-rc.0 +
+ ## 6.0.0 ### Minor Changes diff --git a/packages/ui-contexts/package.json b/packages/ui-contexts/package.json index 9152d21782c2..472d10708bfd 100644 --- a/packages/ui-contexts/package.json +++ b/packages/ui-contexts/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/ui-contexts", - "version": "6.0.0", + "version": "7.0.0", "private": true, "devDependencies": { "@rocket.chat/core-typings": "workspace:^", diff --git a/packages/ui-kit/CHANGELOG.md b/packages/ui-kit/CHANGELOG.md index 59de835f34ad..e2ac676651ec 100644 --- a/packages/ui-kit/CHANGELOG.md +++ b/packages/ui-kit/CHANGELOG.md @@ -1,5 +1,17 @@ # Change Log +## 0.34.0 + +### Minor Changes + +- ([#31918](https://github.com/RocketChat/Rocket.Chat/pull/31918)) Introduced new elements for apps to select channels + +## 0.34.0-rc.0 + +### Minor Changes + +- ([#31918](https://github.com/RocketChat/Rocket.Chat/pull/31918)) Introduced new elements for apps to select channels + ## 0.33.0 ### Minor Changes diff --git a/packages/ui-kit/package.json b/packages/ui-kit/package.json index 23cd40877dfe..321095cf1527 100644 --- a/packages/ui-kit/package.json +++ b/packages/ui-kit/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/ui-kit", - "version": "0.33.0", + "version": "0.34.0", "description": "Interactive UI elements for Rocket.Chat Apps", "homepage": "https://rocket.chat", "author": { diff --git a/packages/ui-video-conf/CHANGELOG.md b/packages/ui-video-conf/CHANGELOG.md index 5244989bae58..50871b70ebd0 100644 --- a/packages/ui-video-conf/CHANGELOG.md +++ b/packages/ui-video-conf/CHANGELOG.md @@ -1,5 +1,45 @@ # @rocket.chat/ui-video-conf +## 7.0.0 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/ui-contexts@7.0.0 + - @rocket.chat/ui-avatar@3.0.0 +
+ +## 7.0.0-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/ui-contexts@7.0.0-rc.2 + - @rocket.chat/ui-avatar@3.0.0-rc.2 +
+ +## 7.0.0-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/ui-contexts@7.0.0-rc.1 + - @rocket.chat/ui-avatar@3.0.0-rc.1 +
+ +## 7.0.0-rc.0 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/ui-contexts@7.0.0-rc.0 + - @rocket.chat/ui-avatar@3.0.0-rc.0 +
+ ## 6.0.0 ### Patch Changes diff --git a/packages/ui-video-conf/package.json b/packages/ui-video-conf/package.json index be30d82d7d9d..2e92e8158113 100644 --- a/packages/ui-video-conf/package.json +++ b/packages/ui-video-conf/package.json @@ -1,14 +1,14 @@ { "name": "@rocket.chat/ui-video-conf", - "version": "6.0.0", + "version": "7.0.0", "private": true, "devDependencies": { "@babel/core": "~7.22.20", "@rocket.chat/css-in-js": "~0.31.25", "@rocket.chat/eslint-config": "workspace:^", - "@rocket.chat/fuselage": "^0.53.7", + "@rocket.chat/fuselage": "^0.54.2", "@rocket.chat/fuselage-hooks": "^0.33.1", - "@rocket.chat/icons": "^0.35.0", + "@rocket.chat/icons": "^0.36.0", "@rocket.chat/styled": "~0.31.25", "@rocket.chat/ui-avatar": "workspace:^", "@rocket.chat/ui-contexts": "workspace:^", @@ -36,8 +36,8 @@ "@rocket.chat/fuselage-hooks": "*", "@rocket.chat/icons": "*", "@rocket.chat/styled": "*", - "@rocket.chat/ui-avatar": "2.0.0", - "@rocket.chat/ui-contexts": "6.0.0", + "@rocket.chat/ui-avatar": "3.0.0", + "@rocket.chat/ui-contexts": "7.0.0", "react": "^17.0.2", "react-dom": "^17.0.2" }, diff --git a/packages/uikit-playground/CHANGELOG.md b/packages/uikit-playground/CHANGELOG.md index bc81f0f24d9f..1de746cfaf6c 100644 --- a/packages/uikit-playground/CHANGELOG.md +++ b/packages/uikit-playground/CHANGELOG.md @@ -1,5 +1,49 @@ # @rocket.chat/uikit-playground +## 0.2.23 + +### Patch Changes + +-
Updated dependencies [6205ef14f0, ee5cdfc367]: + + - @rocket.chat/fuselage-ui-kit@7.0.0 + - @rocket.chat/ui-contexts@7.0.0 + - @rocket.chat/ui-avatar@3.0.0 +
+ +## 0.2.23-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/fuselage-ui-kit@7.0.0-rc.2 + - @rocket.chat/ui-contexts@7.0.0-rc.2 + - @rocket.chat/ui-avatar@3.0.0-rc.2 +
+ +## 0.2.23-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/fuselage-ui-kit@7.0.0-rc.1 + - @rocket.chat/ui-contexts@7.0.0-rc.1 + - @rocket.chat/ui-avatar@3.0.0-rc.1 +
+ +## 0.2.23-rc.0 + +### Patch Changes + +-
Updated dependencies [6205ef14f0, ee5cdfc367]: + + - @rocket.chat/fuselage-ui-kit@7.0.0-rc.0 + - @rocket.chat/ui-contexts@7.0.0-rc.0 + - @rocket.chat/ui-avatar@3.0.0-rc.0 +
+ ## 0.2.22 ### Patch Changes diff --git a/packages/uikit-playground/package.json b/packages/uikit-playground/package.json index 381dd9786545..133faa8c75ee 100644 --- a/packages/uikit-playground/package.json +++ b/packages/uikit-playground/package.json @@ -1,7 +1,7 @@ { "name": "@rocket.chat/uikit-playground", "private": true, - "version": "0.2.22", + "version": "0.2.23", "type": "module", "scripts": { "dev": "vite", @@ -15,13 +15,13 @@ "@codemirror/tooltip": "^0.19.16", "@lezer/highlight": "^1.1.6", "@rocket.chat/css-in-js": "~0.31.25", - "@rocket.chat/fuselage": "^0.53.7", + "@rocket.chat/fuselage": "^0.54.2", "@rocket.chat/fuselage-hooks": "^0.33.1", "@rocket.chat/fuselage-polyfills": "~0.31.25", "@rocket.chat/fuselage-toastbar": "^0.31.26", "@rocket.chat/fuselage-tokens": "^0.33.1", "@rocket.chat/fuselage-ui-kit": "workspace:~", - "@rocket.chat/icons": "^0.35.0", + "@rocket.chat/icons": "^0.36.0", "@rocket.chat/logo": "^0.31.30", "@rocket.chat/styled": "~0.31.25", "@rocket.chat/ui-avatar": "workspace:^", diff --git a/packages/web-ui-registration/CHANGELOG.md b/packages/web-ui-registration/CHANGELOG.md index 310ba1e4abca..16398fd01f1e 100644 --- a/packages/web-ui-registration/CHANGELOG.md +++ b/packages/web-ui-registration/CHANGELOG.md @@ -1,5 +1,41 @@ # @rocket.chat/web-ui-registration +## 7.0.0 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/ui-contexts@7.0.0 +
+ +## 7.0.0-rc.2 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/ui-contexts@7.0.0-rc.2 +
+ +## 7.0.0-rc.1 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/ui-contexts@7.0.0-rc.1 +
+ +## 7.0.0-rc.0 + +### Patch Changes + +-
Updated dependencies []: + + - @rocket.chat/ui-contexts@7.0.0-rc.0 +
+ ## 6.0.0 ### Patch Changes diff --git a/packages/web-ui-registration/package.json b/packages/web-ui-registration/package.json index ab7bd0beb3f2..35bcc20bee17 100644 --- a/packages/web-ui-registration/package.json +++ b/packages/web-ui-registration/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/web-ui-registration", - "version": "6.0.0", + "version": "7.0.0", "private": true, "homepage": "https://rocket.chat", "main": "./dist/index.js", @@ -51,7 +51,7 @@ "peerDependencies": { "@rocket.chat/layout": "*", "@rocket.chat/tools": "0.2.1", - "@rocket.chat/ui-contexts": "6.0.0", + "@rocket.chat/ui-contexts": "7.0.0", "@tanstack/react-query": "*", "react": "*", "react-hook-form": "*", diff --git a/yarn.lock b/yarn.lock index 023a3b4f215b..1f73a73df3e1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8444,7 +8444,7 @@ __metadata: "@rocket.chat/apps-engine": 1.42.2 "@rocket.chat/core-typings": "workspace:^" "@rocket.chat/eslint-config": "workspace:^" - "@rocket.chat/icons": ^0.35.0 + "@rocket.chat/icons": ^0.36.0 "@rocket.chat/message-parser": "workspace:^" "@rocket.chat/models": "workspace:^" "@rocket.chat/rest-typings": "workspace:^" @@ -8469,7 +8469,7 @@ __metadata: dependencies: "@rocket.chat/apps-engine": 1.42.2 "@rocket.chat/eslint-config": "workspace:^" - "@rocket.chat/icons": ^0.35.0 + "@rocket.chat/icons": ^0.36.0 "@rocket.chat/message-parser": "workspace:^" "@rocket.chat/ui-kit": "workspace:~" eslint: ~8.45.0 @@ -8743,11 +8743,11 @@ __metadata: "@rocket.chat/apps-engine": ^1.42.2 "@rocket.chat/core-typings": "workspace:^" "@rocket.chat/eslint-config": "workspace:^" - "@rocket.chat/fuselage": ^0.53.7 + "@rocket.chat/fuselage": ^0.54.2 "@rocket.chat/fuselage-hooks": ^0.33.1 "@rocket.chat/fuselage-polyfills": ~0.31.25 "@rocket.chat/gazzodown": "workspace:^" - "@rocket.chat/icons": ^0.35.0 + "@rocket.chat/icons": ^0.36.0 "@rocket.chat/mock-providers": "workspace:^" "@rocket.chat/prettier-config": ~0.31.25 "@rocket.chat/styled": ~0.31.25 @@ -8795,19 +8795,19 @@ __metadata: "@rocket.chat/icons": "*" "@rocket.chat/prettier-config": "*" "@rocket.chat/styled": "*" - "@rocket.chat/ui-avatar": 2.0.0 - "@rocket.chat/ui-contexts": 6.0.0 - "@rocket.chat/ui-kit": 0.33.0 - "@rocket.chat/ui-video-conf": 6.0.0 + "@rocket.chat/ui-avatar": 3.0.0 + "@rocket.chat/ui-contexts": 7.0.0 + "@rocket.chat/ui-kit": 0.34.0 + "@rocket.chat/ui-video-conf": 7.0.0 "@tanstack/react-query": "*" react: "*" react-dom: "*" languageName: unknown linkType: soft -"@rocket.chat/fuselage@npm:^0.53.7": - version: 0.53.7 - resolution: "@rocket.chat/fuselage@npm:0.53.7" +"@rocket.chat/fuselage@npm:^0.54.2": + version: 0.54.2 + resolution: "@rocket.chat/fuselage@npm:0.54.2" dependencies: "@rocket.chat/css-in-js": ^0.31.25 "@rocket.chat/css-supports": ^0.31.25 @@ -8825,7 +8825,7 @@ __metadata: react: ^17.0.2 react-dom: ^17.0.2 react-virtuoso: 1.2.4 - checksum: 3765c064f9f356b3da3ee147d3700104eebb642ba27807ec25866e8445d8d761c5ad127bafddf171d4913ae92df082ace93fc070f93159fb7d01aba10bd3c2b0 + checksum: 1e49b3324f50525a002dd450a28dc8c6fca559e51c8e93449e167b50ca88767cc3dd11ac3c89ea794597c6c06a4a681aea1043b8f8bb42c49df0362bb5791019 languageName: node linkType: hard @@ -8836,7 +8836,7 @@ __metadata: "@babel/core": ~7.22.20 "@rocket.chat/core-typings": "workspace:^" "@rocket.chat/css-in-js": ~0.31.25 - "@rocket.chat/fuselage": ^0.53.7 + "@rocket.chat/fuselage": ^0.54.2 "@rocket.chat/fuselage-tokens": ^0.33.1 "@rocket.chat/message-parser": "workspace:^" "@rocket.chat/styled": ~0.31.25 @@ -8887,8 +8887,8 @@ __metadata: "@rocket.chat/fuselage-tokens": "*" "@rocket.chat/message-parser": 0.31.29 "@rocket.chat/styled": "*" - "@rocket.chat/ui-client": 6.0.0 - "@rocket.chat/ui-contexts": 6.0.0 + "@rocket.chat/ui-client": 7.0.0 + "@rocket.chat/ui-contexts": 7.0.0 katex: "*" react: "*" languageName: unknown @@ -8909,10 +8909,10 @@ __metadata: languageName: unknown linkType: soft -"@rocket.chat/icons@npm:^0.35.0": - version: 0.35.0 - resolution: "@rocket.chat/icons@npm:0.35.0" - checksum: c31e20255f7349fab3f74abb0a4ccdaa6fcd194fcb00036115458714008d88108caeb713c79ea8ffc6871147c360e96fe4ae2f24d31116c50c7854f64c522701 +"@rocket.chat/icons@npm:^0.36.0": + version: 0.36.0 + resolution: "@rocket.chat/icons@npm:0.36.0" + checksum: ebec57fdfc9bac3b0b29ba43d9ac316b55f6e4177fa4456de195352d6add1e15e25c4d72e6a4fdc3d33abaabf8af0ca7eb0d36badb360113a19c15a13d68aed5 languageName: node linkType: hard @@ -9196,7 +9196,7 @@ __metadata: "@rocket.chat/favicon": "workspace:^" "@rocket.chat/forked-matrix-appservice-bridge": ^4.0.2 "@rocket.chat/forked-matrix-bot-sdk": ^0.6.0-beta.3 - "@rocket.chat/fuselage": ^0.53.7 + "@rocket.chat/fuselage": ^0.54.2 "@rocket.chat/fuselage-hooks": ^0.33.1 "@rocket.chat/fuselage-polyfills": ~0.31.25 "@rocket.chat/fuselage-toastbar": ^0.31.26 @@ -9204,7 +9204,7 @@ __metadata: "@rocket.chat/fuselage-ui-kit": "workspace:^" "@rocket.chat/gazzodown": "workspace:^" "@rocket.chat/i18n": "workspace:^" - "@rocket.chat/icons": ^0.35.0 + "@rocket.chat/icons": ^0.36.0 "@rocket.chat/instance-status": "workspace:^" "@rocket.chat/jwt": "workspace:^" "@rocket.chat/layout": ~0.31.26 @@ -10092,7 +10092,7 @@ __metadata: resolution: "@rocket.chat/ui-avatar@workspace:packages/ui-avatar" dependencies: "@babel/core": ~7.22.20 - "@rocket.chat/fuselage": ^0.53.7 + "@rocket.chat/fuselage": ^0.54.2 "@rocket.chat/ui-contexts": "workspace:^" "@types/babel__core": ~7.20.3 "@types/react": ~17.0.69 @@ -10106,7 +10106,7 @@ __metadata: typescript: ~5.3.3 peerDependencies: "@rocket.chat/fuselage": "*" - "@rocket.chat/ui-contexts": 6.0.0 + "@rocket.chat/ui-contexts": 7.0.0 react: ~17.0.2 languageName: unknown linkType: soft @@ -10118,9 +10118,9 @@ __metadata: "@babel/core": ~7.22.20 "@react-aria/toolbar": ^3.0.0-beta.1 "@rocket.chat/css-in-js": ~0.31.25 - "@rocket.chat/fuselage": ^0.53.7 + "@rocket.chat/fuselage": ^0.54.2 "@rocket.chat/fuselage-hooks": ^0.33.1 - "@rocket.chat/icons": ^0.35.0 + "@rocket.chat/icons": ^0.36.0 "@rocket.chat/mock-providers": "workspace:^" "@rocket.chat/ui-contexts": "workspace:~" "@storybook/addon-actions": ~6.5.16 @@ -10159,7 +10159,7 @@ __metadata: "@rocket.chat/fuselage": "*" "@rocket.chat/fuselage-hooks": "*" "@rocket.chat/icons": "*" - "@rocket.chat/ui-contexts": 6.0.0 + "@rocket.chat/ui-contexts": 7.0.0 react: ~17.0.2 languageName: unknown linkType: soft @@ -10171,8 +10171,8 @@ __metadata: "@babel/core": ~7.22.20 "@react-aria/toolbar": ^3.0.0-beta.1 "@rocket.chat/eslint-config": "workspace:^" - "@rocket.chat/fuselage": ^0.53.7 - "@rocket.chat/icons": ^0.35.0 + "@rocket.chat/fuselage": ^0.54.2 + "@rocket.chat/icons": ^0.36.0 "@storybook/addon-actions": ~6.5.16 "@storybook/addon-docs": ~6.5.16 "@storybook/addon-essentials": ~6.5.16 @@ -10263,9 +10263,9 @@ __metadata: resolution: "@rocket.chat/ui-theming@workspace:ee/packages/ui-theming" dependencies: "@rocket.chat/css-in-js": ~0.31.25 - "@rocket.chat/fuselage": ^0.53.7 + "@rocket.chat/fuselage": ^0.54.2 "@rocket.chat/fuselage-hooks": ^0.33.1 - "@rocket.chat/icons": ^0.35.0 + "@rocket.chat/icons": ^0.36.0 "@rocket.chat/ui-contexts": "workspace:~" "@storybook/addon-actions": ~6.5.16 "@storybook/addon-docs": ~6.5.16 @@ -10306,9 +10306,9 @@ __metadata: "@rocket.chat/css-in-js": ~0.31.25 "@rocket.chat/emitter": ~0.31.25 "@rocket.chat/eslint-config": "workspace:^" - "@rocket.chat/fuselage": ^0.53.7 + "@rocket.chat/fuselage": ^0.54.2 "@rocket.chat/fuselage-hooks": ^0.33.1 - "@rocket.chat/icons": ^0.35.0 + "@rocket.chat/icons": ^0.36.0 "@rocket.chat/styled": ~0.31.25 "@rocket.chat/ui-avatar": "workspace:^" "@rocket.chat/ui-contexts": "workspace:^" @@ -10335,8 +10335,8 @@ __metadata: "@rocket.chat/fuselage-hooks": "*" "@rocket.chat/icons": "*" "@rocket.chat/styled": "*" - "@rocket.chat/ui-avatar": 2.0.0 - "@rocket.chat/ui-contexts": 6.0.0 + "@rocket.chat/ui-avatar": 3.0.0 + "@rocket.chat/ui-contexts": 7.0.0 react: ^17.0.2 react-dom: ^17.0.2 languageName: unknown @@ -10351,13 +10351,13 @@ __metadata: "@codemirror/tooltip": ^0.19.16 "@lezer/highlight": ^1.1.6 "@rocket.chat/css-in-js": ~0.31.25 - "@rocket.chat/fuselage": ^0.53.7 + "@rocket.chat/fuselage": ^0.54.2 "@rocket.chat/fuselage-hooks": ^0.33.1 "@rocket.chat/fuselage-polyfills": ~0.31.25 "@rocket.chat/fuselage-toastbar": ^0.31.26 "@rocket.chat/fuselage-tokens": ^0.33.1 "@rocket.chat/fuselage-ui-kit": "workspace:~" - "@rocket.chat/icons": ^0.35.0 + "@rocket.chat/icons": ^0.36.0 "@rocket.chat/logo": ^0.31.30 "@rocket.chat/styled": ~0.31.25 "@rocket.chat/ui-avatar": "workspace:^" @@ -10426,7 +10426,7 @@ __metadata: peerDependencies: "@rocket.chat/layout": "*" "@rocket.chat/tools": 0.2.1 - "@rocket.chat/ui-contexts": 6.0.0 + "@rocket.chat/ui-contexts": 7.0.0 "@tanstack/react-query": "*" react: "*" react-hook-form: "*" @@ -36857,7 +36857,7 @@ __metadata: "@rocket.chat/core-services": "workspace:^" "@rocket.chat/core-typings": "workspace:^" "@rocket.chat/emitter": ~0.31.25 - "@rocket.chat/icons": ^0.35.0 + "@rocket.chat/icons": ^0.36.0 "@rocket.chat/message-parser": "workspace:^" "@rocket.chat/model-typings": "workspace:^" "@rocket.chat/models": "workspace:^"