From 04c008e8828785ee22e875229d7dc3d22ff7c67b Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Fri, 12 Mar 2021 15:31:03 -0600 Subject: [PATCH 1/8] Improve: Increase testing coverage (#21015) --- app/settings/server/raw.tests.js | 47 ++++++++ client/lib/minimongo/comparisons.spec.ts | 130 +++++++++++++++++++++++ package-lock.json | 51 +++++---- package.json | 2 + 4 files changed, 212 insertions(+), 18 deletions(-) create mode 100644 app/settings/server/raw.tests.js create mode 100644 client/lib/minimongo/comparisons.spec.ts diff --git a/app/settings/server/raw.tests.js b/app/settings/server/raw.tests.js new file mode 100644 index 000000000000..7a9d6bccd6cf --- /dev/null +++ b/app/settings/server/raw.tests.js @@ -0,0 +1,47 @@ +/* eslint-env mocha */ +import chai, { expect } from 'chai'; +import spies from 'chai-spies'; +import rewire from 'rewire'; + +chai.use(spies); + +describe('Raw Settings', () => { + let rawModule; + const cache = new Map(); + + before('rewire deps', () => { + const spy = chai.spy(async (id) => { + if (id === '1') { return 'some-setting-value'; } + return null; + }); + + rawModule = rewire('./raw'); + rawModule.__set__('setFromDB', spy); + rawModule.__set__('cache', cache); + }); + + it('should get the value from database when it isnt in cache', async () => { + const setting = await rawModule.getValue('1'); + + expect(setting).to.be.equal('some-setting-value'); + }); + + it('should get the value from cache when its available', async () => { + cache.set('2', 'supeer-setting'); + const setting = await rawModule.getValue('2'); + + expect(setting).to.be.equal('supeer-setting'); + }); + + it('should update the value in cache', async () => { + await rawModule.updateValue('2', { value: 'not-super-setting' }); + + expect(cache.get('2')).to.be.equal('not-super-setting'); + }); + + it('should not update the setting if the new value is undefined', async () => { + await rawModule.updateValue('2', {}); + + expect(cache.get('2')).to.be.equal('not-super-setting'); + }); +}); diff --git a/client/lib/minimongo/comparisons.spec.ts b/client/lib/minimongo/comparisons.spec.ts new file mode 100644 index 000000000000..488e091f4e8c --- /dev/null +++ b/client/lib/minimongo/comparisons.spec.ts @@ -0,0 +1,130 @@ +import chai from 'chai'; +import { describe, it } from 'mocha'; + +import { equals, isObject, flatSome, some, isEmptyArray } from './comparisons'; + +describe('Comparisons service', () => { + describe('equals', () => { + it('should return true if two numbers are equal', () => { + chai.expect(equals(1, 1)).to.be.equal(true); + }); + + it('should return false if arguments are null or undefined', () => { + chai.expect(equals(undefined, null)).to.be.equal(false); + chai.expect(equals(null, undefined)).to.be.equal(false); + }); + + it('should return false if arguments arent objects and they are not the same', () => { + chai.expect(equals('not', 'thesame')).to.be.equal(false); + }); + + it('should return true if date objects provided have the same value', () => { + const currentDate = new Date(); + + chai.expect(equals(currentDate, currentDate)).to.be.equal(true); + }); + + it('should return true if 2 equal UInt8Array are provided', () => { + const arr1 = new Uint8Array([1, 2]); + const arr2 = new Uint8Array([1, 2]); + + chai.expect(equals(arr1, arr2)).to.be.equal(true); + }); + + it('should return true if 2 equal arrays are provided', () => { + const arr1 = [1, 2, 4]; + const arr2 = [1, 2, 4]; + + chai.expect(equals(arr1, arr2)).to.be.equal(true); + }); + + it('should return false if 2 arrays with different length are provided', () => { + const arr1 = [1, 4, 5]; + const arr2 = [1, 4, 5, 7]; + + chai.expect(equals(arr1, arr2)).to.be.equal(false); + }); + + it('should return true if the objects provided are "equal"', () => { + const obj = { a: 1 }; + const obj2 = obj; + + chai.expect(equals(obj, obj2)).to.be.equal(true); + }); + + it('should return true if both objects have the same keys', () => { + const obj = { a: 1 }; + const obj2 = { a: 1 }; + + chai.expect(equals(obj, obj2)).to.be.equal(true); + }); + }); + + describe('isObject', () => { + it('should return true if value is an object or function', () => { + const obj = {}; + const func = (a: any): any => a; + + chai.expect(isObject(obj)).to.be.equal(true); + chai.expect(isObject(func)).to.be.equal(true); + }); + + it('should return false for other data types', () => { + chai.expect(isObject(1)).to.be.equal(false); + chai.expect(isObject(true)).to.be.equal(false); + chai.expect(isObject('212')).to.be.equal(false); + }); + }); + + describe('flatSome', () => { + it('should run .some on array', () => { + const arr = [1, 2, 4, 6, 9]; + const isEven = (v: number): boolean => v % 2 === 0; + + chai.expect(flatSome(arr, isEven)).to.be.equal(true); + }); + + it('should run the function on the value when its not an array', () => { + const val = 1; + const isEven = (v: number): boolean => v % 2 === 0; + + chai.expect(flatSome(val, isEven)).to.be.equal(false); + }); + }); + + describe('some', () => { + it('should run .some on array', () => { + const arr = [1, 2, 4, 6, 9]; + const isEven = (v: number | number[]): boolean => { + if (Array.isArray(v)) { return false; } + return v % 2 === 0; + }; + + chai.expect(some(arr, isEven)).to.be.equal(true); + }); + + it('should run the function on the value when its not an array', () => { + const val = 1; + const isEven = (v: number | number[]): boolean => { + if (Array.isArray(v)) { return false; } + return v % 2 === 0; + }; + + chai.expect(some(val, isEven)).to.be.equal(false); + }); + }); + + describe('isEmptyArray', () => { + it('should return true if array is empty', () => { + chai.expect(isEmptyArray([])).to.be.equal(true); + }); + + it('should return false if value is not an array', () => { + chai.expect(isEmptyArray(1)).to.be.equal(false); + }); + + it('should return false if array is not empty', () => { + chai.expect(isEmptyArray([1, 2])).to.be.equal(false); + }); + }); +}); diff --git a/package-lock.json b/package-lock.json index 07658333a6ed..77c56ed8c864 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11125,6 +11125,12 @@ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" }, + "@types/rewire": { + "version": "2.5.28", + "resolved": "https://registry.npmjs.org/@types/rewire/-/rewire-2.5.28.tgz", + "integrity": "sha512-uD0j/AQOa5le7afuK+u+woi8jNKF1vf3DN0H7LCJhft/lNNibUr7VcAesdgtWfEKveZol3ZG1CJqwx2Bhrnl8w==", + "dev": true + }, "@types/semver": { "version": "7.3.3", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.3.tgz", @@ -19929,7 +19935,7 @@ }, "chownr": { "version": "1.1.1", - "resolved": "", + "resolved": false, "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", "dev": true, "optional": true @@ -19964,7 +19970,7 @@ }, "debug": { "version": "4.1.1", - "resolved": "", + "resolved": false, "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "optional": true, @@ -19995,7 +20001,7 @@ }, "fs-minipass": { "version": "1.2.5", - "resolved": "", + "resolved": false, "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", "dev": true, "optional": true, @@ -20029,7 +20035,7 @@ }, "glob": { "version": "7.1.3", - "resolved": "", + "resolved": false, "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "optional": true, @@ -20061,7 +20067,7 @@ }, "ignore-walk": { "version": "3.0.1", - "resolved": "", + "resolved": false, "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", "dev": true, "optional": true, @@ -20082,7 +20088,7 @@ }, "inherits": { "version": "2.0.3", - "resolved": "", + "resolved": false, "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true, "optional": true @@ -20130,7 +20136,7 @@ }, "minipass": { "version": "2.3.5", - "resolved": "", + "resolved": false, "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, "optional": true, @@ -20141,7 +20147,7 @@ }, "minizlib": { "version": "1.2.1", - "resolved": "", + "resolved": false, "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", "dev": true, "optional": true, @@ -20161,7 +20167,7 @@ }, "ms": { "version": "2.1.1", - "resolved": "", + "resolved": false, "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true, "optional": true @@ -20175,7 +20181,7 @@ }, "needle": { "version": "2.3.0", - "resolved": "", + "resolved": false, "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==", "dev": true, "optional": true, @@ -20187,7 +20193,7 @@ }, "node-pre-gyp": { "version": "0.12.0", - "resolved": "", + "resolved": false, "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", "dev": true, "optional": true, @@ -20217,14 +20223,14 @@ }, "npm-bundled": { "version": "1.0.6", - "resolved": "", + "resolved": false, "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", "dev": true, "optional": true }, "npm-packlist": { "version": "1.4.1", - "resolved": "", + "resolved": false, "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", "dev": true, "optional": true, @@ -20304,7 +20310,7 @@ }, "process-nextick-args": { "version": "2.0.0", - "resolved": "", + "resolved": false, "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true, "optional": true @@ -20349,7 +20355,7 @@ }, "rimraf": { "version": "2.6.3", - "resolved": "", + "resolved": false, "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "optional": true, @@ -20380,7 +20386,7 @@ }, "semver": { "version": "5.7.0", - "resolved": "", + "resolved": false, "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true, "optional": true @@ -20440,7 +20446,7 @@ }, "tar": { "version": "4.4.8", - "resolved": "", + "resolved": false, "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", "dev": true, "optional": true, @@ -20480,7 +20486,7 @@ }, "yallist": { "version": "3.0.3", - "resolved": "", + "resolved": false, "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", "dev": true, "optional": true @@ -32243,6 +32249,15 @@ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true }, + "rewire": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/rewire/-/rewire-5.0.0.tgz", + "integrity": "sha512-1zfitNyp9RH5UDyGGLe9/1N0bMlPQ0WrX0Tmg11kMHBpqwPJI4gfPpP7YngFyLbFmhXh19SToAG0sKKEFcOIJA==", + "dev": true, + "requires": { + "eslint": "^6.8.0" + } + }, "rimraf": { "version": "2.4.5", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", diff --git a/package.json b/package.json index 10084ed72af8..297ac09fa736 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "@types/mongodb": "^3.5.26", "@types/node": "^10.12.14", "@types/react-dom": "^16.9.8", + "@types/rewire": "^2.5.28", "@types/semver": "^7.3.3", "@types/toastr": "^2.1.38", "@typescript-eslint/eslint-plugin": "^2.34.0", @@ -115,6 +116,7 @@ "postcss-url": "^8.0.0", "progress": "^2.0.3", "proxyquire": "^2.1.3", + "rewire": "^5.0.0", "simple-git": "^1.107.0", "source-map": "^0.5.7", "stylelint": "^13.6.1", From 978cd3a845b01a164e5b9fd7b82ad41d9a3ef4c8 Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Fri, 12 Mar 2021 18:32:41 -0300 Subject: [PATCH 2/8] Chore: Meteor update 2.1 (#21061) --- .docker-mongo/Dockerfile | 2 +- .docker/Dockerfile | 2 +- .github/workflows/build_and_test.yml | 14 ++++----- .meteor/packages | 28 ++++++++---------- .meteor/release | 2 +- .meteor/versions | 44 ++++++++++++++-------------- .snapcraft/resources/preparenode | 2 +- 7 files changed, 46 insertions(+), 48 deletions(-) diff --git a/.docker-mongo/Dockerfile b/.docker-mongo/Dockerfile index 672ed4da6ba0..0c2e69a1d385 100644 --- a/.docker-mongo/Dockerfile +++ b/.docker-mongo/Dockerfile @@ -1,4 +1,4 @@ -FROM node:12.18.4-buster-slim +FROM node:12.21.0-buster-slim LABEL maintainer="buildmaster@rocket.chat" diff --git a/.docker/Dockerfile b/.docker/Dockerfile index 355b08eb0ab4..ff6fe47826f8 100644 --- a/.docker/Dockerfile +++ b/.docker/Dockerfile @@ -1,4 +1,4 @@ -FROM node:12.18.4-buster-slim +FROM node:12.21.0-buster-slim LABEL maintainer="buildmaster@rocket.chat" diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 6faffea2b518..896257497796 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -30,10 +30,10 @@ jobs: echo "github.event_name: ${{ github.event_name }}" cat $GITHUB_EVENT_PATH - - name: Use Node.js 12.18.4 + - name: Use Node.js 12.21.0 uses: actions/setup-node@v2 with: - node-version: "12.18.4" + node-version: "12.21.0" - uses: actions/checkout@v2 @@ -190,7 +190,7 @@ jobs: strategy: matrix: - node-version: ["12.18.4"] + node-version: ["12.21.0"] mongodb-version: ["3.4", "3.6", "4.0"] steps: @@ -312,10 +312,10 @@ jobs: path: ~/.meteor key: ${{ runner.OS }}-meteor-${{ hashFiles('.meteor/release') }}-${{ hashFiles('.github/workflows/build_and_test.yml') }} - - name: Use Node.js 12.18.4 + - name: Use Node.js 12.21.0 uses: actions/setup-node@v2 with: - node-version: "12.18.4" + node-version: "12.21.0" - name: Install Meteor run: | @@ -542,10 +542,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Use Node.js 12.18.4 + - name: Use Node.js 12.21.0 uses: actions/setup-node@v2 with: - node-version: "12.18.4" + node-version: "12.21.0" - name: Login to DockerHub uses: docker/login-action@v1 diff --git a/.meteor/packages b/.meteor/packages index 2a2c903bbd21..02d1834c4f7b 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -9,29 +9,28 @@ accounts-facebook@1.3.2 accounts-github@1.4.3 accounts-google@1.3.3 accounts-meteor-developer@1.4.2 -accounts-password@1.6.2 +accounts-password@1.7.0 accounts-twitter@1.4.2 blaze-html-templates check@1.3.1 ddp-rate-limiter@1.0.9 ddp-common@1.4.0 -dynamic-import@0.5.2 -ecmascript@0.14.3 -typescript@3.7.6 +dynamic-import@0.6.0 +ecmascript@0.15.0 +typescript@4.1.2 ejson@1.1.1 email@2.0.0 fastclick@1.0.13 http@1.4.2 -jquery@1.11.10 -logging@1.1.20 +logging@1.2.0 meteor-base@1.4.0 mobile-experience@1.1.0 -mongo@1.10.0 +mongo@1.10.1 random@1.2.0 rate-limit@1.0.9 reactive-dict@1.3.0 reactive-var@1.0.11 -reload@1.3.0 +reload@1.3.1 service-configuration@1.0.11 session@1.2.0 shell-server@0.5.0 @@ -47,7 +46,6 @@ rocketchat:version konecty:multiple-instances-status konecty:user-presence -deepwell:bootstrap-datepicker2 dispatch:run-as-user jalik:ufs@1.0.2 jalik:ufs-gridfs@1.0.2 @@ -70,22 +68,22 @@ littledata:synced-cron edgee:slingshot jalik:ufs-local@1.0.2 -accounts-base@1.7.0 +accounts-base@1.8.0 accounts-oauth@1.2.0 -autoupdate@1.6.0 -babel-compiler@7.5.3 +autoupdate@1.7.0 +babel-compiler@7.6.0 google-oauth@1.3.0 htmljs less matb33:collection-hooks meteorhacks:inject-initial -oauth@1.3.0 +oauth@1.3.2 oauth2@1.3.0 routepolicy@1.1.0 sha@1.0.9 templating -webapp@1.9.1 -webapp-hashing@1.0.9 +webapp@1.10.0 +webapp-hashing@1.1.0 rocketchat:oauth2-server rocketchat:i18n rocketchat:postcss diff --git a/.meteor/release b/.meteor/release index 019e3aefb00f..fd169bc4792f 100644 --- a/.meteor/release +++ b/.meteor/release @@ -1 +1 @@ -METEOR@1.11.1 +METEOR@2.1 diff --git a/.meteor/versions b/.meteor/versions index 811fbd386ad1..5bcc27eebe93 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -1,15 +1,15 @@ -accounts-base@1.7.0 +accounts-base@1.8.0 accounts-facebook@1.3.2 accounts-github@1.4.3 accounts-google@1.3.3 accounts-meteor-developer@1.4.2 accounts-oauth@1.2.0 -accounts-password@1.6.2 +accounts-password@1.7.0 accounts-twitter@1.4.2 aldeed:simple-schema@1.5.4 allow-deny@1.1.0 -autoupdate@1.6.0 -babel-compiler@7.5.3 +autoupdate@1.7.0 +babel-compiler@7.6.0 babel-runtime@1.5.0 base64@1.0.12 binary-heap@1.0.11 @@ -25,16 +25,15 @@ check@1.3.1 coffeescript@1.0.17 dandv:caret-position@2.1.1 ddp@1.4.0 -ddp-client@2.3.3 +ddp-client@2.4.0 ddp-common@1.4.0 ddp-rate-limiter@1.0.9 ddp-server@2.3.2 -deepwell:bootstrap-datepicker2@1.3.0 deps@1.0.12 diff-sequence@1.1.1 dispatch:run-as-user@1.1.1 -dynamic-import@0.5.2 -ecmascript@0.14.3 +dynamic-import@0.6.0 +ecmascript@0.15.0 ecmascript-runtime@0.7.0 ecmascript-runtime-client@0.11.0 ecmascript-runtime-server@0.10.0 @@ -42,7 +41,7 @@ edgee:slingshot@0.7.1 ejson@1.1.1 email@2.0.0 es5-shim@4.8.0 -facebook-oauth@1.7.0 +facebook-oauth@1.7.4 facts-base@1.0.1 fastclick@1.0.13 fetch@0.1.1 @@ -52,7 +51,7 @@ google-oauth@1.3.0 hot-code-push@1.0.4 html-tools@1.0.11 htmljs@1.0.11 -http@1.4.2 +http@1.4.3 id-map@1.1.0 inter-process-messaging@0.1.1 jalik:ufs@1.0.2 @@ -71,25 +70,25 @@ less@3.0.1 littledata:synced-cron@1.5.1 livedata@1.0.18 localstorage@1.2.0 -logging@1.1.20 +logging@1.2.0 matb33:collection-hooks@1.0.1 mdg:validation-error@0.5.1 meteor@1.9.3 meteor-base@1.4.0 -meteor-developer-oauth@1.2.1 +meteor-developer-oauth@1.2.3 meteorhacks:inject-initial@1.0.4 meteorspark:util@0.2.0 minifier-css@1.5.3 minifier-js@2.6.0 -minimongo@1.6.0 +minimongo@1.6.1 mizzao:timesync@0.3.4 mobile-experience@1.1.0 mobile-status-bar@1.1.0 modern-browsers@0.1.5 -modules@0.15.0 +modules@0.16.0 modules-runtime@0.12.0 -mongo@1.10.0 -mongo-decimal@0.1.1 +mongo@1.10.1 +mongo-decimal@0.1.2 mongo-dev-server@1.1.0 mongo-id@1.0.7 mrt:reactive-store@0.0.1 @@ -98,12 +97,12 @@ nimble:restivus@0.8.12 nooitaf:colors@1.1.2_1 npm-bcrypt@0.9.3 npm-mongo@3.8.1 -oauth@1.3.0 +oauth@1.3.2 oauth1@1.3.0 oauth2@1.3.0 observe-sequence@1.0.16 ordered-dict@1.1.0 -ostrio:cookies@2.6.0 +ostrio:cookies@2.7.0 pauli:accounts-linkedin@5.0.0 pauli:linkedin-oauth@5.0.0 promise@0.11.2 @@ -112,9 +111,10 @@ raix:handlebar-helpers@0.2.5 raix:ui-dropped-event@0.0.7 random@1.2.0 rate-limit@1.0.9 +react-fast-refresh@0.1.0 reactive-dict@1.3.0 reactive-var@1.0.11 -reload@1.3.0 +reload@1.3.1 retry@1.1.0 rocketchat:i18n@0.0.1 rocketchat:livechat@0.0.1 @@ -141,9 +141,9 @@ templating-runtime@1.3.2 templating-tools@1.1.2 tracker@1.2.0 twitter-oauth@1.2.0 -typescript@3.7.6 +typescript@4.1.2 ui@1.0.13 underscore@1.0.10 url@1.3.1 -webapp@1.9.1 -webapp-hashing@1.0.9 +webapp@1.10.0 +webapp-hashing@1.1.0 diff --git a/.snapcraft/resources/preparenode b/.snapcraft/resources/preparenode index abe5bba3afa7..1a293dcdac3e 100755 --- a/.snapcraft/resources/preparenode +++ b/.snapcraft/resources/preparenode @@ -1,6 +1,6 @@ #!/bin/bash -node_version="v12.18.4" +node_version="v12.21.0" unamem="$(uname -m)" if [[ $unamem == *aarch64* ]]; then From 0298910e9dfa4093ab44403e5c23914b8c620af3 Mon Sep 17 00:00:00 2001 From: Martin Schoeler Date: Tue, 16 Mar 2021 15:23:34 -0300 Subject: [PATCH 3/8] [FIX] Use the correct icons for DMs (#21125) * [FIX] Use the correct icons for DMs * Prefer `balloon` icon over `message` icon Co-authored-by: Tasso Evangelista --- app/lib/lib/roomTypes/direct.js | 2 +- client/hooks/useRoomIcon.tsx | 2 +- client/sidebar/header/actions/CreateRoomList.js | 6 +++--- client/views/admin/info/UsageCard.js | 2 +- client/views/admin/users/UserInfoActions.js | 2 +- client/views/room/hooks/useUserInfoActions.js | 2 +- package-lock.json | 7 ++++--- package.json | 2 +- 8 files changed, 13 insertions(+), 12 deletions(-) diff --git a/app/lib/lib/roomTypes/direct.js b/app/lib/lib/roomTypes/direct.js index 02863802f806..dc0b7561e138 100644 --- a/app/lib/lib/roomTypes/direct.js +++ b/app/lib/lib/roomTypes/direct.js @@ -40,7 +40,7 @@ export class DirectMessageRoomType extends RoomTypeConfig { getIcon(roomData) { if (this.isGroupChat(roomData)) { - return 'team'; + return 'balloon'; } return this.icon; } diff --git a/client/hooks/useRoomIcon.tsx b/client/hooks/useRoomIcon.tsx index dd3df78be422..5e7eef708228 100644 --- a/client/hooks/useRoomIcon.tsx +++ b/client/hooks/useRoomIcon.tsx @@ -26,7 +26,7 @@ export const useRoomIcon = (room: IRoom, small = true): JSX.Element | { name: st case 'd': const direct = room as unknown as IDirectMessageRoom; if (direct.uids && direct.uids.length > 2) { - return { name: 'baloon-arrow-left' }; + return { name: 'balloon' }; } if (direct.uids && direct.uids.length > 0) { return uid !== room.u._id)[0] || room.u._id } as any } />; diff --git a/client/sidebar/header/actions/CreateRoomList.js b/client/sidebar/header/actions/CreateRoomList.js index f0e28758db0b..6513c88bab1c 100644 --- a/client/sidebar/header/actions/CreateRoomList.js +++ b/client/sidebar/header/actions/CreateRoomList.js @@ -68,9 +68,9 @@ function CreateRoomList() {
    - {canCreateChannel && } - {canCreateDirectMessages && } - {discussionEnabled && canCreateDiscussion && } + {canCreateChannel && } + {canCreateDirectMessages && } + {discussionEnabled && canCreateDiscussion && }
; diff --git a/client/views/admin/info/UsageCard.js b/client/views/admin/info/UsageCard.js index e784c5787f78..b15295e92b0e 100644 --- a/client/views/admin/info/UsageCard.js +++ b/client/views/admin/info/UsageCard.js @@ -108,7 +108,7 @@ const UsageCard = React.memo(function UsageCard({ statistics, isLoading, vertica value={s(() => statistics.totalPrivateGroups)} /> {t('Stats_Total_Direct_Messages')}} + label={<> {t('Stats_Total_Direct_Messages')}} value={s(() => statistics.totalDirect)} /> ({ ...canDirectMessage && { directMessage: { - icon: 'chat', + icon: 'balloon', label: t('Direct_Message'), action: directMessageClick, } }, diff --git a/client/views/room/hooks/useUserInfoActions.js b/client/views/room/hooks/useUserInfoActions.js index 6addbeb7c6f9..5e1593e43f36 100644 --- a/client/views/room/hooks/useUserInfoActions.js +++ b/client/views/room/hooks/useUserInfoActions.js @@ -167,7 +167,7 @@ export const useUserInfoActions = (user = {}, rid) => { const openDirectMessageOption = useMemo(() => shouldOpenDirectMessage && { label: t('Direct_Message'), - icon: 'chat', + icon: 'balloon', action: openDirectDm, }, [openDirectDm, shouldOpenDirectMessage, t]); diff --git a/package-lock.json b/package-lock.json index 77c56ed8c864..49922984aeec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6035,9 +6035,10 @@ } }, "@rocket.chat/icons": { - "version": "0.6.3-dev.179", - "resolved": "https://registry.npmjs.org/@rocket.chat/icons/-/icons-0.6.3-dev.179.tgz", - "integrity": "sha512-5NsrdR3C90Z0lR7OkgzHGqjDVPxho+LUjrv15F1L/uONp/WdQBo+Z3cGFXUgnLZf5ohX1BgTRRtzHtJPPr7QyQ==" + "version": "0.6.3-dev.202", + "resolved": "https://registry.npmjs.org/@rocket.chat/icons/-/icons-0.6.3-dev.202.tgz", + "integrity": "sha512-Tsg7wdHWiUunhyWTAa+pO9m6bdM3wLJ+t3jYfSUXn9FsumHsR7f+g4GjSJsHvw65Ly3b5TJcs917YKCtb/h5Gg==", + "dev": true }, "@rocket.chat/livechat": { "version": "1.8.0", diff --git a/package.json b/package.json index 297ac09fa736..dfb75973f9a8 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "@babel/register": "^7.12.1", "@octokit/rest": "^16.43.2", "@rocket.chat/eslint-config": "^0.3.0", + "@rocket.chat/icons": "^0.6.3-dev.202", "@rocket.chat/livechat": "^1.8.0", "@settlin/spacebars-loader": "^1.0.8", "@storybook/addon-essentials": "^6.1.11", @@ -144,7 +145,6 @@ "@rocket.chat/fuselage-polyfills": "^0.6.3-dev.181", "@rocket.chat/fuselage-tokens": "^0.21.0", "@rocket.chat/fuselage-ui-kit": "^0.6.3-dev.184", - "@rocket.chat/icons": "^0.6.3-dev.179", "@rocket.chat/mp3-encoder": "^0.6.3-dev.178", "@rocket.chat/ui-kit": "^0.6.3-dev.178", "@slack/client": "^4.12.0", From 9611e2b62fe18aed88c732f2c20c9a16baff0e16 Mon Sep 17 00:00:00 2001 From: Tiago Evangelista Pinto Date: Wed, 17 Mar 2021 23:05:09 -0300 Subject: [PATCH 4/8] [FIX] Unexpected open or close visitor info (#21094) * fix unexpected open or close visitor info * fix lgtm bot warning Co-authored-by: Tasso Evangelista Co-authored-by: Tasso Evangelista Co-authored-by: Renato Becker --- app/ui/client/views/app/room.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/ui/client/views/app/room.js b/app/ui/client/views/app/room.js index 25df13abe97d..87614468e85b 100644 --- a/app/ui/client/views/app/room.js +++ b/app/ui/client/views/app/room.js @@ -888,9 +888,10 @@ Meteor.startup(() => { return; } - const room = Rooms.findOne({ _id: rid }); + let room = Rooms.findOne({ _id: rid }, { fields: { t: 1 } }); if (room?.t === 'l') { + room = Tracker.nonreactive(() => Rooms.findOne({ _id: rid })); roomTypes.getConfig(room.t).openCustomProfileTab(this, room, room.v.username); } }); From eba1e9b3146e5102baed000953c2cb51930c345c Mon Sep 17 00:00:00 2001 From: meomay503 Date: Fri, 19 Mar 2021 19:00:57 +0700 Subject: [PATCH 5/8] [NEW] use _rocketchatLogger in Apps debugLog (#21000) --- app/apps/server/orchestrator.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/apps/server/orchestrator.js b/app/apps/server/orchestrator.js index 612fe2bdf8a6..f2b2d52b081c 100644 --- a/app/apps/server/orchestrator.js +++ b/app/apps/server/orchestrator.js @@ -115,8 +115,7 @@ export class AppServerOrchestrator { debugLog(...args) { if (this.isDebugging()) { - // eslint-disable-next-line - console.log(...args); + this.getRocketChatLogger().debug(...args); } } From 49b5f89d70bbc72112fcb52c1db18b1486023925 Mon Sep 17 00:00:00 2001 From: Lucas Sartor Chauvin Date: Fri, 19 Mar 2021 17:24:34 -0300 Subject: [PATCH 6/8] [IMPROVE] Improve Apps permission modal (#21193) * improve modal design * add en and pt-BR translations * fix icon size --- client/views/admin/apps/AppPermissionsReviewModal.js | 11 +++++++---- packages/rocketchat-i18n/i18n/en.i18n.json | 5 +++-- packages/rocketchat-i18n/i18n/pt-BR.i18n.json | 5 +++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/client/views/admin/apps/AppPermissionsReviewModal.js b/client/views/admin/apps/AppPermissionsReviewModal.js index 687f173f9d6c..b8c1efadc79d 100644 --- a/client/views/admin/apps/AppPermissionsReviewModal.js +++ b/client/views/admin/apps/AppPermissionsReviewModal.js @@ -26,17 +26,20 @@ const AppPermissionsReviewModal = ({ return - + {t('Apps_Permissions_Review_Modal_Title')} + + {t('Apps_Permissions_Review_Modal_Subtitle')} +
    { appPermissions.length - ? appPermissions.map((permission) => + ? appPermissions.map((permission, count) =>
  • - { t(`Apps_Permissions_${ permission.name.replace('.', '_') }`) } + { count + 1 } - { t(`Apps_Permissions_${ permission.name.replace('.', '_') }`) } { permission.required && ({ t('required') }) }
  • ) : t('Apps_Permissions_No_Permissions_Required') @@ -46,7 +49,7 @@ const AppPermissionsReviewModal = ({ - + ; diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index a588448c1d0d..ebd6742346ab 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -462,7 +462,8 @@ "Apps_Marketplace_Uninstall_App_Prompt": "Do you really want to uninstall this app?", "Apps_Marketplace_Uninstall_Subscribed_App_Anyway": "Uninstall it anyway", "Apps_Marketplace_Uninstall_Subscribed_App_Prompt": "This app has an active subscription and uninstalling will not cancel it. If you'd like to do that, please modify your subscription before uninstalling.", - "Apps_Permissions_Review_Modal_Title": "This app requires the following permissions", + "Apps_Permissions_Review_Modal_Title": "Required Permissions", + "Apps_Permissions_Review_Modal_Subtitle": "This app would like access to the following permissions. Do you agree?", "Apps_Permissions_No_Permissions_Required": "The App does not require additional permissions", "Apps_Permissions_user_read": "Access user information", "Apps_Permissions_user_write": "Modify user information", @@ -4298,4 +4299,4 @@ "Your_temporary_password_is_password": "Your temporary password is [password].", "Your_TOTP_has_been_reset": "Your Two Factor TOTP has been reset.", "Your_workspace_is_ready": "Your workspace is ready to use 🎉" -} \ No newline at end of file +} diff --git a/packages/rocketchat-i18n/i18n/pt-BR.i18n.json b/packages/rocketchat-i18n/i18n/pt-BR.i18n.json index e50ddf1dca2d..e88be2b5a5d5 100644 --- a/packages/rocketchat-i18n/i18n/pt-BR.i18n.json +++ b/packages/rocketchat-i18n/i18n/pt-BR.i18n.json @@ -403,7 +403,8 @@ "Apps_Marketplace_pricingPlan_yearly_perUser": "__price__/ano por usuário", "Apps_Marketplace_Uninstall_App_Prompt": "Você quer mesmo desinstalar este aplicativo?", "Apps_Marketplace_Uninstall_Subscribed_App_Anyway": "Desinstalar mesmo assim", - "Apps_Permissions_Review_Modal_Title": "Este app necessita das seguintes permissões", + "Apps_Permissions_Review_Modal_Title": "Permissões Necessárias", + "Apps_Permissions_Review_Modal_Subtitle": "Este app gostaria de acessar as seguintes permissões. Você aceita?", "Apps_Permissions_No_Permissions_Required": "Este app não necessita de nenhuma permissão", "Apps_Permissions_user_read": "Acessar dados de usuários", "Apps_Permissions_user_write": "Alterar dados de usuários", @@ -3641,4 +3642,4 @@ "Your_question": "A sua pergunta", "Your_server_link": "O link do seu servidor", "Your_workspace_is_ready": "O seu espaço de trabalho está pronto a usar 🎉" -} \ No newline at end of file +} From c163bf9c58b3c4abfb57b66ce2c1277268b95f94 Mon Sep 17 00:00:00 2001 From: Lucas Sartor Chauvin Date: Fri, 19 Mar 2021 18:21:00 -0300 Subject: [PATCH 7/8] [NEW][APPS] Map description as a room value in Apps (#20811) * map 'description' as a room value * Update Apps-Engine version --- app/apps/server/converters/rooms.js | 1 + package-lock.json | 49 ++++++++++++++++------------- package.json | 2 +- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/app/apps/server/converters/rooms.js b/app/apps/server/converters/rooms.js index df7f43f94c6b..6333058a25b3 100644 --- a/app/apps/server/converters/rooms.js +++ b/app/apps/server/converters/rooms.js @@ -120,6 +120,7 @@ export class AppRoomsConverter { isWaitingResponse: 'waitingResponse', isOpen: 'open', _USERNAMES: '_USERNAMES', + description: 'description', isDefault: (room) => { const result = !!room.default; delete room.default; diff --git a/package-lock.json b/package-lock.json index 49922984aeec..144bcdb39113 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5907,9 +5907,9 @@ } }, "@rocket.chat/apps-engine": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/@rocket.chat/apps-engine/-/apps-engine-1.23.0.tgz", - "integrity": "sha512-SDHVt+vDJaUHLk5nyiufhn9GjZbEJtP7ORjqilipB2RK5rtVnlJJJCtO1MgTI/A9LvLJBCESkC7u6PmUDrQ+/A==", + "version": "1.24.0-alpha.4777", + "resolved": "https://registry.npmjs.org/@rocket.chat/apps-engine/-/apps-engine-1.24.0-alpha.4777.tgz", + "integrity": "sha512-c7oiK0G1WvXfY2b16wTfds+WpSYBGQ9U3VW8hD0MXqbiv/TrwsBcGvJo0K9aj/aFM3qP1rqXW7gUE5aCr4h1ZA==", "requires": { "adm-zip": "^0.4.9", "cryptiles": "^4.1.3", @@ -5917,6 +5917,13 @@ "semver": "^5.5.0", "stack-trace": "0.0.10", "uuid": "^3.2.1" + }, + "dependencies": { + "adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==" + } } }, "@rocket.chat/css-in-js": { @@ -19936,7 +19943,7 @@ }, "chownr": { "version": "1.1.1", - "resolved": false, + "resolved": "", "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", "dev": true, "optional": true @@ -19971,7 +19978,7 @@ }, "debug": { "version": "4.1.1", - "resolved": false, + "resolved": "", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "optional": true, @@ -20002,7 +20009,7 @@ }, "fs-minipass": { "version": "1.2.5", - "resolved": false, + "resolved": "", "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", "dev": true, "optional": true, @@ -20036,7 +20043,7 @@ }, "glob": { "version": "7.1.3", - "resolved": false, + "resolved": "", "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "optional": true, @@ -20068,7 +20075,7 @@ }, "ignore-walk": { "version": "3.0.1", - "resolved": false, + "resolved": "", "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", "dev": true, "optional": true, @@ -20089,7 +20096,7 @@ }, "inherits": { "version": "2.0.3", - "resolved": false, + "resolved": "", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true, "optional": true @@ -20137,7 +20144,7 @@ }, "minipass": { "version": "2.3.5", - "resolved": false, + "resolved": "", "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, "optional": true, @@ -20148,7 +20155,7 @@ }, "minizlib": { "version": "1.2.1", - "resolved": false, + "resolved": "", "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", "dev": true, "optional": true, @@ -20168,7 +20175,7 @@ }, "ms": { "version": "2.1.1", - "resolved": false, + "resolved": "", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true, "optional": true @@ -20182,7 +20189,7 @@ }, "needle": { "version": "2.3.0", - "resolved": false, + "resolved": "", "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==", "dev": true, "optional": true, @@ -20194,7 +20201,7 @@ }, "node-pre-gyp": { "version": "0.12.0", - "resolved": false, + "resolved": "", "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", "dev": true, "optional": true, @@ -20224,14 +20231,14 @@ }, "npm-bundled": { "version": "1.0.6", - "resolved": false, + "resolved": "", "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", "dev": true, "optional": true }, "npm-packlist": { "version": "1.4.1", - "resolved": false, + "resolved": "", "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", "dev": true, "optional": true, @@ -20311,7 +20318,7 @@ }, "process-nextick-args": { "version": "2.0.0", - "resolved": false, + "resolved": "", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true, "optional": true @@ -20356,7 +20363,7 @@ }, "rimraf": { "version": "2.6.3", - "resolved": false, + "resolved": "", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "optional": true, @@ -20387,7 +20394,7 @@ }, "semver": { "version": "5.7.0", - "resolved": false, + "resolved": "", "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true, "optional": true @@ -20447,7 +20454,7 @@ }, "tar": { "version": "4.4.8", - "resolved": false, + "resolved": "", "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", "dev": true, "optional": true, @@ -20487,7 +20494,7 @@ }, "yallist": { "version": "3.0.3", - "resolved": false, + "resolved": "", "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", "dev": true, "optional": true diff --git a/package.json b/package.json index dfb75973f9a8..ff0c82aaea9f 100644 --- a/package.json +++ b/package.json @@ -137,7 +137,7 @@ "@nivo/heatmap": "^0.61.0", "@nivo/line": "^0.61.1", "@nivo/pie": "^0.61.1", - "@rocket.chat/apps-engine": "1.23.0", + "@rocket.chat/apps-engine": "1.24.0-alpha.4777", "@rocket.chat/css-in-js": "^0.6.3-dev.180", "@rocket.chat/emitter": "^0.6.3-dev.185", "@rocket.chat/fuselage": "^0.6.3-dev.188", From 9bbf11ad53d43dc3a5d870d6df4a3022b6de3440 Mon Sep 17 00:00:00 2001 From: Rodrigo Nascimento Date: Sat, 20 Mar 2021 15:44:15 -0300 Subject: [PATCH 8/8] [FIX] Wrong license seats number administration info panel (#21222) * Use active users to display on limit of users for the license on info panel * Print more info about issues with licenses on server --- client/views/admin/info/LicenseCard.js | 2 +- ee/app/license/server/license.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/client/views/admin/info/LicenseCard.js b/client/views/admin/info/LicenseCard.js index fe42b59d37ed..a162ee196ded 100644 --- a/client/views/admin/info/LicenseCard.js +++ b/client/views/admin/info/LicenseCard.js @@ -74,7 +74,7 @@ const LicenseCard = ({ statistics, isLoading }) => { ? :