Upgrading most of the webapp dependencies. (#2642)
* Most of the frontend libraries upgraded * Upgrading the dependencies in mattermost-plugin * Fixing some tiny poblems * All jest tests passing * Some other small upgrades and tests are passing * Fixing compass-icons * Fixing eslint * Fixing unit test * Fixing unit test
This commit is contained in:
parent
3dba5c8fcd
commit
5df336cf46
48 changed files with 14788 additions and 20947 deletions
14912
mattermost-plugin/webapp/package-lock.json
generated
14912
mattermost-plugin/webapp/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -14,71 +14,71 @@
|
|||
"check-types": "tsc"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "7.16.8",
|
||||
"@babel/core": "7.16.12",
|
||||
"@babel/plugin-proposal-class-properties": "7.13.0",
|
||||
"@babel/plugin-proposal-object-rest-spread": "7.14.2",
|
||||
"@babel/plugin-proposal-optional-chaining": "7.14.2",
|
||||
"@babel/cli": "7.17.6",
|
||||
"@babel/core": "7.17.8",
|
||||
"@babel/plugin-proposal-class-properties": "7.16.7",
|
||||
"@babel/plugin-proposal-object-rest-spread": "7.17.3",
|
||||
"@babel/plugin-proposal-optional-chaining": "7.16.7",
|
||||
"@babel/plugin-syntax-dynamic-import": "7.8.3",
|
||||
"@babel/polyfill": "7.10.4",
|
||||
"@babel/preset-env": "7.14.2",
|
||||
"@babel/preset-react": "7.13.13",
|
||||
"@babel/preset-typescript": "7.13.0",
|
||||
"@babel/runtime": "7.14.0",
|
||||
"@formatjs/ts-transformer": "3.4.2",
|
||||
"@types/enzyme": "3.10.8",
|
||||
"@types/jest": "26.0.23",
|
||||
"@types/node": "15.6.1",
|
||||
"@types/react": "17.0.6",
|
||||
"@types/react-dom": "17.0.5",
|
||||
"@babel/preset-env": "7.16.11",
|
||||
"@babel/preset-react": "7.16.7",
|
||||
"@babel/preset-typescript": "7.16.7",
|
||||
"@babel/runtime": "7.17.8",
|
||||
"@formatjs/ts-transformer": "3.9.2",
|
||||
"@types/enzyme": "3.10.11",
|
||||
"@types/jest": "27.4.1",
|
||||
"@types/node": "17.0.23",
|
||||
"@types/react": "17.0.42",
|
||||
"@types/react-dom": "17.0.14",
|
||||
"@types/react-intl": "3.0.0",
|
||||
"@types/react-redux": "7.1.16",
|
||||
"@types/react-router-dom": "5.1.7",
|
||||
"@types/react-transition-group": "4.4.1",
|
||||
"@typescript-eslint/eslint-plugin": "4.25.0",
|
||||
"@typescript-eslint/parser": "4.25.0",
|
||||
"@types/react-redux": "7.1.23",
|
||||
"@types/react-router-dom": "5.3.3",
|
||||
"@types/react-transition-group": "4.4.4",
|
||||
"@typescript-eslint/eslint-plugin": "5.16.0",
|
||||
"@typescript-eslint/parser": "5.16.0",
|
||||
"babel-eslint": "10.1.0",
|
||||
"babel-jest": "27.0.1",
|
||||
"babel-loader": "8.2.2",
|
||||
"babel-plugin-typescript-to-proptypes": "1.4.2",
|
||||
"css-loader": "5.2.6",
|
||||
"eslint": "7.27.0",
|
||||
"eslint-import-resolver-webpack": "0.13.1",
|
||||
"babel-jest": "27.5.1",
|
||||
"babel-loader": "8.2.4",
|
||||
"babel-plugin-typescript-to-proptypes": "2.0.0",
|
||||
"css-loader": "6.7.1",
|
||||
"eslint": "8.11.0",
|
||||
"eslint-import-resolver-webpack": "0.13.2",
|
||||
"eslint-plugin-babel": "^5.3.1",
|
||||
"eslint-plugin-cypress": "2.11.2",
|
||||
"eslint-plugin-cypress": "2.12.1",
|
||||
"eslint-plugin-header": "3.1.1",
|
||||
"eslint-plugin-import": "2.23.3",
|
||||
"eslint-plugin-import": "2.25.4",
|
||||
"eslint-plugin-jquery": "1.5.1",
|
||||
"eslint-plugin-mattermost": "github:mattermost/eslint-plugin-mattermost#070ce792d105482ffb2b27cfc0b7e78b3d20acee",
|
||||
"eslint-plugin-no-only-tests": "2.4.0",
|
||||
"eslint-plugin-react": "7.23.2",
|
||||
"eslint-plugin-react-hooks": "4.2.0",
|
||||
"eslint-plugin-no-only-tests": "2.6.0",
|
||||
"eslint-plugin-react": "7.29.4",
|
||||
"eslint-plugin-react-hooks": "4.3.0",
|
||||
"file-loader": "6.2.0",
|
||||
"identity-obj-proxy": "3.0.0",
|
||||
"image-webpack-loader": "8.1.0",
|
||||
"imagemin-gifsicle": "^7.0.0",
|
||||
"imagemin-mozjpeg": "^9.0.0",
|
||||
"imagemin-mozjpeg": "^10.0.0",
|
||||
"imagemin-optipng": "^8.0.0",
|
||||
"imagemin-pngquant": "^9.0.2",
|
||||
"imagemin-svgo": "^8.0.0",
|
||||
"imagemin-svgo": "^10.0.1",
|
||||
"imagemin-webp": "7.0.0",
|
||||
"jest": "27.0.1",
|
||||
"jest": "27.5.1",
|
||||
"jest-canvas-mock": "2.3.1",
|
||||
"jest-junit": "12.0.0",
|
||||
"sass": "1.25.0",
|
||||
"sass-loader": "11.1.1",
|
||||
"style-loader": "2.0.0",
|
||||
"ts-loader": "9.2.3",
|
||||
"typescript": "4.2.4",
|
||||
"webpack": "5.37.1",
|
||||
"webpack-cli": "4.7.0"
|
||||
"jest-junit": "13.0.0",
|
||||
"sass": "1.49.9",
|
||||
"sass-loader": "12.6.0",
|
||||
"style-loader": "3.3.1",
|
||||
"ts-loader": "9.2.8",
|
||||
"typescript": "4.6.2",
|
||||
"webpack": "5.70.0",
|
||||
"webpack-cli": "4.9.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "3.12.1",
|
||||
"core-js": "3.21.1",
|
||||
"glob-parent": "6.0.2",
|
||||
"marked": ">=4.0.12",
|
||||
"mattermost-redux": "5.33.1",
|
||||
"react-intl": "^5.13.5",
|
||||
"react-intl": "^5.24.7",
|
||||
"react-router-dom": "5.2.0",
|
||||
"trim-newlines": "4.0.2"
|
||||
},
|
||||
|
|
|
@ -112,20 +112,10 @@ module.exports = {
|
|||
},
|
||||
{
|
||||
test: /\.(png|eot|tiff|svg|woff2|woff|ttf|jpg|gif)$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[name].[ext]',
|
||||
outputPath: 'static',
|
||||
publicPath: '/static/',
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'image-webpack-loader',
|
||||
options: {},
|
||||
},
|
||||
],
|
||||
type: 'asset/resource',
|
||||
generator: {
|
||||
filename: 'static/[name].[ext]',
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"extends": [
|
||||
"plugin:mattermost/react",
|
||||
"plugin:react/recommended",
|
||||
"plugin:cypress/recommended",
|
||||
"plugin:jquery/deprecated"
|
||||
],
|
||||
"plugins": [
|
||||
"react",
|
||||
"babel",
|
||||
"mattermost",
|
||||
"import",
|
||||
"cypress",
|
||||
"jquery",
|
||||
|
@ -25,6 +25,12 @@
|
|||
}
|
||||
},
|
||||
"rules": {
|
||||
"react/display-name": [
|
||||
0,
|
||||
{
|
||||
"ignoreTranspilerName": false
|
||||
}
|
||||
],
|
||||
"max-lines": "off",
|
||||
"no-unused-expressions": 0,
|
||||
"babel/no-unused-expressions": [2, {"allowShortCircuit": true}],
|
||||
|
@ -71,6 +77,7 @@
|
|||
"plugin:@typescript-eslint/recommended"
|
||||
],
|
||||
"rules": {
|
||||
"mattermost/no-dispatch-getstate": 0, // Failing in eslint 8
|
||||
"import/no-unresolved": 0, // ts handles this better
|
||||
"camelcase": 0,
|
||||
"semi": "off",
|
||||
|
|
20343
webapp/package-lock.json
generated
20343
webapp/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -23,29 +23,30 @@
|
|||
"cypress:open": "cypress open"
|
||||
},
|
||||
"dependencies": {
|
||||
"@draft-js-plugins/editor": "^4.1.0",
|
||||
"@draft-js-plugins/emoji": "^4.5.5",
|
||||
"@draft-js-plugins/mention": "^5.0.0",
|
||||
"@fullcalendar/core": "^5.10.0",
|
||||
"@fullcalendar/daygrid": "^5.10.0",
|
||||
"@fullcalendar/interaction": "^5.10.0",
|
||||
"@fullcalendar/react": "^5.10.0",
|
||||
"@mattermost/compass-icons": "^0.1.10",
|
||||
"@reduxjs/toolkit": "^1.6.0",
|
||||
"@draft-js-plugins/editor": "^4.1.2",
|
||||
"@draft-js-plugins/emoji": "^4.6.0",
|
||||
"@draft-js-plugins/mention": "^5.1.2",
|
||||
"@fullcalendar/core": "^5.10.1",
|
||||
"@fullcalendar/daygrid": "^5.10.1",
|
||||
"@fullcalendar/interaction": "^5.10.1",
|
||||
"@fullcalendar/react": "^5.10.1",
|
||||
"@mattermost/compass-icons": "^0.1.22",
|
||||
"@reduxjs/toolkit": "^1.8.0",
|
||||
"@tippyjs/react": "4.2.6",
|
||||
"color": "^4.0.0",
|
||||
"color": "^4.2.1",
|
||||
"draft-js": "^0.11.7",
|
||||
"emoji-mart": "^3.0.1",
|
||||
"fstream": "^1.0.12",
|
||||
"fullcalendar": "^5.10.0",
|
||||
"fullcalendar": "^5.10.2",
|
||||
"imagemin-gifsicle": "^7.0.0",
|
||||
"imagemin-mozjpeg": "^9.0.0",
|
||||
"imagemin-mozjpeg": "^10.0.0",
|
||||
"imagemin-optipng": "^8.0.0",
|
||||
"imagemin-pngquant": "^9.0.2",
|
||||
"imagemin-svgo": "^8.0.0",
|
||||
"imagemin-svgo": "^10.0.1",
|
||||
"imagemin-webp": "^7.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"marked": "^4.0.12",
|
||||
"mini-create-react-context": "^0.4.1",
|
||||
"moment": "^2.29.1",
|
||||
"nanoevents": "^5.1.13",
|
||||
"react": "^17.0.2",
|
||||
|
@ -55,11 +56,11 @@
|
|||
"react-dnd-scrolling": "^1.2.1",
|
||||
"react-dnd-touch-backend": "^14.0.0",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-hot-keys": "^2.6.2",
|
||||
"react-hotkeys-hook": "^3.3.0",
|
||||
"react-intl": "^5.13.5",
|
||||
"react-redux": "^7.2.4",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-hot-keys": "^2.7.1",
|
||||
"react-hotkeys-hook": "^3.4.4",
|
||||
"react-intl": "^5.24.7",
|
||||
"react-redux": "^7.2.6",
|
||||
"react-router-dom": "^5.2.1",
|
||||
"react-select": "^4.3.0",
|
||||
"trim-newlines": "^4.0.2"
|
||||
},
|
||||
|
@ -74,8 +75,13 @@
|
|||
}
|
||||
},
|
||||
"transform": {
|
||||
"^.+\\.tsx?$": "ts-jest"
|
||||
"^.+\\.tsx?$": "@swc/jest"
|
||||
},
|
||||
"transformIgnorePatterns": [
|
||||
"/nanoevents/"
|
||||
],
|
||||
"maxWorkers": "50%",
|
||||
"testEnvironment": "jsdom",
|
||||
"collectCoverage": true,
|
||||
"collectCoverageFrom": [
|
||||
"src/**/*.{ts,tsx,js,jsx}",
|
||||
|
@ -83,67 +89,69 @@
|
|||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@formatjs/cli": "^3.2.0",
|
||||
"@formatjs/ts-transformer": "^3.2.1",
|
||||
"@formatjs/cli": "^4.8.2",
|
||||
"@formatjs/ts-transformer": "^3.9.2",
|
||||
"@swc/jest": "^0.2.20",
|
||||
"@testing-library/cypress": "^8.0.2",
|
||||
"@testing-library/dom": "^7.31.2",
|
||||
"@testing-library/jest-dom": "^5.11.10",
|
||||
"@testing-library/dom": "^8.11.4",
|
||||
"@testing-library/jest-dom": "^5.16.3",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^13.1.9",
|
||||
"@types/color": "^3.0.2",
|
||||
"@types/draft-js": "^0.11.6",
|
||||
"@types/emoji-mart": "^3.0.4",
|
||||
"@types/jest": "^26.0.21",
|
||||
"@types/marked": "^4.0.1",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@types/color": "^3.0.3",
|
||||
"@types/draft-js": "^0.11.9",
|
||||
"@types/emoji-mart": "^3.0.9",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/marked": "^4.0.3",
|
||||
"@types/nanoevents": "^1.0.0",
|
||||
"@types/react": "^17.0.3",
|
||||
"@types/react-dom": "^17.0.3",
|
||||
"@types/react": "^17.0.43",
|
||||
"@types/react-dom": "^17.0.14",
|
||||
"@types/react-intl": "^3.0.0",
|
||||
"@types/react-redux": "^7.1.16",
|
||||
"@types/react-router-dom": "^5.1.7",
|
||||
"@types/react-redux": "^7.1.23",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"@types/react-select": "^4.0.13",
|
||||
"@types/redux-mock-store": "^1.0.3",
|
||||
"@typescript-eslint/eslint-plugin": "^4.19.0",
|
||||
"@typescript-eslint/parser": "^4.19.0",
|
||||
"copy-webpack-plugin": "^8.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.16.0",
|
||||
"@typescript-eslint/parser": "^5.16.0",
|
||||
"copy-webpack-plugin": "^10.2.4",
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "^5.2.0",
|
||||
"cypress": "^9.5.0",
|
||||
"cypress-failed-log": "^2.9.2",
|
||||
"cypress-real-events": "^1.6.0",
|
||||
"eslint": "^7.22.0",
|
||||
"eslint-import-resolver-webpack": "0.13.0",
|
||||
"css-loader": "^6.7.1",
|
||||
"cypress": "^9.5.2",
|
||||
"cypress-failed-log": "^2.9.5",
|
||||
"cypress-real-events": "^1.7.0",
|
||||
"eslint": "^8.11.0",
|
||||
"eslint-import-resolver-webpack": "0.13.2",
|
||||
"eslint-plugin-babel": "^5.3.1",
|
||||
"eslint-plugin-cypress": "2.11.2",
|
||||
"eslint-plugin-cypress": "2.12.1",
|
||||
"eslint-plugin-header": "3.1.1",
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"eslint-plugin-import": "2.25.4",
|
||||
"eslint-plugin-jquery": "1.5.1",
|
||||
"eslint-plugin-mattermost": "github:mattermost/eslint-plugin-mattermost#070ce792d105482ffb2b27cfc0b7e78b3d20acee",
|
||||
"eslint-plugin-no-only-tests": "2.4.0",
|
||||
"eslint-plugin-react": "7.23.1",
|
||||
"eslint-plugin-no-only-tests": "2.6.0",
|
||||
"eslint-plugin-react": "7.29.4",
|
||||
"fetch-mock-jest": "^1.5.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"html-webpack-plugin": "^5.3.1",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"image-webpack-loader": "^8.1.0",
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"jest": "^26.6.3",
|
||||
"prettier": "^2.2.1",
|
||||
"jest": "^27.5.1",
|
||||
"jest-mock": "^27.5.1",
|
||||
"prettier": "^2.6.1",
|
||||
"redux-mock-store": "^1.5.4",
|
||||
"sass": "^1.32.8",
|
||||
"sass-loader": "^11.0.1",
|
||||
"start-server-and-test": "^1.12.1",
|
||||
"style-loader": "^2.0.0",
|
||||
"stylelint": "^13.13.1",
|
||||
"stylelint-config-sass-guidelines": "^8.0.0",
|
||||
"terser-webpack-plugin": "^5.1.1",
|
||||
"ts-jest": "^26.5.4",
|
||||
"ts-loader": "^8.0.18",
|
||||
"typescript": "^4.2.3",
|
||||
"webpack": "^5.28.0",
|
||||
"webpack-cli": "^4.5.0",
|
||||
"webpack-merge": "^5.7.3"
|
||||
"sass": "^1.49.9",
|
||||
"sass-loader": "^12.6.0",
|
||||
"start-server-and-test": "^1.14.0",
|
||||
"style-loader": "^3.3.1",
|
||||
"stylelint": "^14.6.1",
|
||||
"stylelint-config-sass-guidelines": "^9.0.1",
|
||||
"terser-webpack-plugin": "^5.3.1",
|
||||
"ts-jest": "^27.1.4",
|
||||
"ts-loader": "^9.2.8",
|
||||
"typescript": "^4.6.3",
|
||||
"webpack": "^5.70.0",
|
||||
"webpack-cli": "^4.9.2",
|
||||
"webpack-merge": "^5.8.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"cypress": "^6.8.0"
|
||||
"cypress": "^9.5.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {createFilterClause} from './blocks/filterClause'
|
||||
|
||||
|
|
|
@ -2403,15 +2403,15 @@ exports[`src/components/workspace show add new view tooltip 1`] = `
|
|||
data-escaped=""
|
||||
data-placement="bottom-start"
|
||||
data-reference-hidden=""
|
||||
data-state="hidden"
|
||||
data-state="visible"
|
||||
role="tooltip"
|
||||
style="max-width: 320px; transition-duration: 0ms;"
|
||||
style="max-width: 320px; transition-duration: 250ms;"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="tippy-content"
|
||||
data-state="hidden"
|
||||
style="transition-duration: 0ms;"
|
||||
data-state="visible"
|
||||
style="transition-duration: 250ms;"
|
||||
>
|
||||
<div>
|
||||
<div>
|
||||
|
|
|
@ -6,7 +6,7 @@ import {render, screen, waitFor} from '@testing-library/react'
|
|||
|
||||
import '@testing-library/jest-dom'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react'
|
||||
import {fireEvent, render, screen} from '@testing-library/react'
|
||||
import {fireEvent, render, screen, act} from '@testing-library/react'
|
||||
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
import '@testing-library/jest-dom'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import mutator from '../mutator'
|
||||
|
||||
|
@ -82,19 +82,24 @@ describe('components/blockIconSelector', () => {
|
|||
expect(mockedMutator.changeBlockIcon).toBeCalledTimes(1)
|
||||
})
|
||||
|
||||
test('return a new icon after click on EmojiPicker', async () => {
|
||||
const {container} = render(wrapIntl(
|
||||
test('return a new icon after click on EmojiPicker', () => {
|
||||
const {container, getByRole, getAllByRole} = render(wrapIntl(
|
||||
<BlockIconSelector
|
||||
block={card}
|
||||
size='l'
|
||||
/>,
|
||||
))
|
||||
userEvent.click(screen.getByRole('button', {name: 'menuwrapper'}))
|
||||
act(() => {
|
||||
userEvent.click(getByRole('button', {name: 'menuwrapper'}))
|
||||
})
|
||||
const menuPicker = container.querySelector('div#pick')
|
||||
expect(menuPicker).not.toBeNull()
|
||||
fireEvent.mouseEnter(menuPicker!)
|
||||
|
||||
const allButtonThumbUp = await screen.findAllByRole('button', {name: /thumbsup/i})
|
||||
act(() => {
|
||||
fireEvent.mouseEnter(menuPicker!)
|
||||
})
|
||||
|
||||
const allButtonThumbUp = getAllByRole('button', {name: /thumbsup/i})
|
||||
userEvent.click(allButtonThumbUp[0])
|
||||
expect(mockedMutator.changeBlockIcon).toBeCalledTimes(1)
|
||||
expect(mockedMutator.changeBlockIcon).toBeCalledWith(card.boardId, card.id, card.fields.icon, '👍')
|
||||
|
|
|
@ -6,7 +6,7 @@ import React from 'react'
|
|||
import {MockStoreEnhanced} from 'redux-mock-store'
|
||||
import {createMemoryHistory} from 'history'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {Provider as ReduxProvider} from 'react-redux'
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import {Provider as ReduxProvider} from 'react-redux'
|
|||
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {FetchMock} from '../../test/fetchMock'
|
||||
import {TestBlockFactory} from '../../test/testBlockFactory'
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import React from 'react'
|
||||
import {render, screen, act} from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
import '@testing-library/jest-dom'
|
||||
import {createIntl} from 'react-intl'
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import React from 'react'
|
|||
import {Provider as ReduxProvider} from 'react-redux'
|
||||
import moment from 'moment'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {wrapIntl, mockStateStore} from '../../testUtils'
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import userEvent from '@testing-library/user-event'
|
|||
|
||||
import React from 'react'
|
||||
import {Provider as ReduxProvider} from 'react-redux'
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import mutator from '../mutator'
|
||||
import {Utils} from '../utils'
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {fireEvent, render, screen, within} from '@testing-library/react'
|
||||
import {fireEvent, render, screen, within, act} from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import React from 'react'
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
import {Provider as ReduxProvider} from 'react-redux'
|
||||
|
||||
import {mockDOM, mockStateStore, wrapDNDIntl} from '../testUtils'
|
||||
|
@ -277,9 +277,11 @@ describe('components/centerPanel', () => {
|
|||
</ReduxProvider>,
|
||||
))
|
||||
|
||||
const cardElement = screen.getByRole('textbox', {name: 'card1'})
|
||||
expect(cardElement).not.toBeNull()
|
||||
userEvent.click(cardElement, {shiftKey: true})
|
||||
act(() => {
|
||||
const cardElement = screen.getByRole('textbox', {name: 'card1'})
|
||||
expect(cardElement.parentNode).not.toBeNull()
|
||||
userEvent.click(cardElement as HTMLElement, {shiftKey: true})
|
||||
})
|
||||
expect(container).toMatchSnapshot()
|
||||
|
||||
//escape
|
||||
|
@ -303,16 +305,20 @@ describe('components/centerPanel', () => {
|
|||
</ReduxProvider>,
|
||||
))
|
||||
|
||||
//select card1
|
||||
const card1Element = screen.getByRole('textbox', {name: 'card1'})
|
||||
expect(card1Element).not.toBeNull()
|
||||
userEvent.click(card1Element, {shiftKey: true})
|
||||
act(() => {
|
||||
//select card1
|
||||
const card1Element = screen.getByRole('textbox', {name: 'card1'})
|
||||
expect(card1Element).not.toBeNull()
|
||||
userEvent.click(card1Element, {shiftKey: true})
|
||||
})
|
||||
expect(container).toMatchSnapshot()
|
||||
|
||||
//select card2
|
||||
const card2Element = screen.getByRole('textbox', {name: 'card2'})
|
||||
expect(card2Element).not.toBeNull()
|
||||
userEvent.click(card2Element, {shiftKey: true, ctrlKey: true})
|
||||
act(() => {
|
||||
//select card2
|
||||
const card2Element = screen.getByRole('textbox', {name: 'card2'})
|
||||
expect(card2Element).not.toBeNull()
|
||||
userEvent.click(card2Element, {shiftKey: true, ctrlKey: true})
|
||||
})
|
||||
expect(container).toMatchSnapshot()
|
||||
|
||||
//escape
|
||||
|
@ -335,9 +341,11 @@ describe('components/centerPanel', () => {
|
|||
/>
|
||||
</ReduxProvider>,
|
||||
))
|
||||
const cardElement = screen.getByRole('textbox', {name: 'card1'})
|
||||
expect(cardElement).not.toBeNull()
|
||||
userEvent.click(cardElement, {shiftKey: true})
|
||||
act(() => {
|
||||
const cardElement = screen.getByRole('textbox', {name: 'card1'})
|
||||
expect(cardElement).not.toBeNull()
|
||||
userEvent.click(cardElement, {shiftKey: true})
|
||||
})
|
||||
expect(container).toMatchSnapshot()
|
||||
|
||||
//delete
|
||||
|
@ -360,9 +368,11 @@ describe('components/centerPanel', () => {
|
|||
/>
|
||||
</ReduxProvider>,
|
||||
))
|
||||
const cardElement = screen.getByRole('textbox', {name: 'card1'})
|
||||
expect(cardElement).not.toBeNull()
|
||||
userEvent.click(cardElement, {shiftKey: true})
|
||||
act(() => {
|
||||
const cardElement = screen.getByRole('textbox', {name: 'card1'})
|
||||
expect(cardElement).not.toBeNull()
|
||||
userEvent.click(cardElement, {shiftKey: true})
|
||||
})
|
||||
expect(container).toMatchSnapshot()
|
||||
|
||||
//ctrl+d
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import React, {ReactElement, ReactNode} from 'react'
|
||||
import {fireEvent, render, screen, waitFor} from '@testing-library/react'
|
||||
import '@testing-library/jest-dom'
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
import {wrapIntl} from '../../testUtils'
|
||||
|
|
|
@ -6,7 +6,7 @@ import {render} from '@testing-library/react'
|
|||
|
||||
import {act} from 'react-dom/test-utils'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {ImageBlock} from '../../blocks/imageBlock'
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import {Provider as ReduxProvider} from 'react-redux'
|
|||
|
||||
import '@testing-library/jest-dom'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {TextBlock} from '../../blocks/textBlock'
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import '@testing-library/jest-dom'
|
|||
import {act, render, screen} from '@testing-library/react'
|
||||
|
||||
import React, {ReactNode, ReactElement} from 'react'
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
import {Provider as ReduxProvider} from 'react-redux'
|
||||
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
|
|
@ -8,7 +8,7 @@ import {Provider as ReduxProvider} from 'react-redux'
|
|||
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {wrapDNDIntl, mockStateStore, blocksById} from '../../testUtils'
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import {Provider as ReduxProvider} from 'react-redux'
|
|||
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {MockStoreEnhanced} from 'redux-mock-store'
|
||||
|
||||
|
|
|
@ -5,12 +5,12 @@ import React from 'react'
|
|||
import {Provider as ReduxProvider} from 'react-redux'
|
||||
import {createMemoryHistory} from 'history'
|
||||
|
||||
import {render} from '@testing-library/react'
|
||||
import {render, act} from '@testing-library/react'
|
||||
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import configureStore from 'redux-mock-store'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {wrapIntl} from '../../testUtils'
|
||||
|
||||
|
@ -77,8 +77,12 @@ describe('components/sidebar/GlobalHeaderSettingsMenu', () => {
|
|||
)
|
||||
|
||||
const {container} = render(component)
|
||||
userEvent.click(container.querySelector('.menu-entry') as Element)
|
||||
userEvent.hover(container.querySelector('#lang') as Element)
|
||||
act(() => {
|
||||
userEvent.click(container.querySelector('.menu-entry') as Element)
|
||||
})
|
||||
act(() => {
|
||||
userEvent.hover(container.querySelector('#lang') as Element)
|
||||
})
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
|
@ -91,8 +95,12 @@ describe('components/sidebar/GlobalHeaderSettingsMenu', () => {
|
|||
)
|
||||
|
||||
const {container} = render(component)
|
||||
userEvent.click(container.querySelector('.menu-entry') as Element)
|
||||
userEvent.hover(container.querySelector('#import') as Element)
|
||||
act(() => {
|
||||
userEvent.click(container.querySelector('.menu-entry') as Element)
|
||||
})
|
||||
act(() => {
|
||||
userEvent.hover(container.querySelector('#import') as Element)
|
||||
})
|
||||
expect(container).toMatchSnapshot()
|
||||
|
||||
userEvent.click(container.querySelector('[aria-label="Asana"]') as Element)
|
||||
|
|
|
@ -373,6 +373,7 @@ exports[`components/kanban/calculations/KanbanCalculationOptions with submenu op
|
|||
</span>
|
||||
<div
|
||||
class="dropdown-submenu"
|
||||
style="top: -10px; left: 0px;"
|
||||
>
|
||||
<div
|
||||
class="drops "
|
||||
|
|
|
@ -6,7 +6,7 @@ import '@testing-library/jest-dom'
|
|||
import React from 'react'
|
||||
import {Provider as ReduxProvider} from 'react-redux'
|
||||
import {MemoryRouter} from 'react-router-dom'
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
import {IPropertyOption, IPropertyTemplate} from '../../blocks/board'
|
||||
|
|
|
@ -9,7 +9,7 @@ import {Provider as ReduxProvider} from 'react-redux'
|
|||
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import Mutator from '../../mutator'
|
||||
import {Utils} from '../../utils'
|
||||
|
|
|
@ -4,7 +4,7 @@ import React from 'react'
|
|||
import {fireEvent, render, screen, within} from '@testing-library/react'
|
||||
import {createIntl} from 'react-intl'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
import {Provider as ReduxProvider} from 'react-redux'
|
||||
|
||||
import Mutator from '../../mutator'
|
||||
|
|
|
@ -5,7 +5,7 @@ import {render, screen, within} from '@testing-library/react'
|
|||
import '@testing-library/jest-dom'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import {createIntl} from 'react-intl'
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {wrapDNDIntl} from '../../testUtils'
|
||||
import Mutator from '../../mutator'
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import React, {useState} from 'react'
|
||||
import {render, screen} from '@testing-library/react'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import '@testing-library/jest-dom'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
|
|
@ -7,7 +7,7 @@ import thunk from 'redux-thunk'
|
|||
|
||||
import React from 'react'
|
||||
import {MemoryRouter} from 'react-router'
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {IUser} from '../../user'
|
||||
import {ISharing} from '../../blocks/sharing'
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
import React from 'react'
|
||||
import {Provider as ReduxProvider} from 'react-redux'
|
||||
|
||||
import {render} from '@testing-library/react'
|
||||
import {render, act} from '@testing-library/react'
|
||||
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import configureStore from 'redux-mock-store'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {wrapIntl} from '../../testUtils'
|
||||
|
||||
|
@ -73,8 +73,12 @@ describe('components/sidebar/SidebarSettingsMenu', () => {
|
|||
)
|
||||
|
||||
const {container} = render(component)
|
||||
userEvent.click(container.querySelector('.menu-entry') as Element)
|
||||
userEvent.hover(container.querySelector('#theme') as Element)
|
||||
act(() => {
|
||||
userEvent.click(container.querySelector('.menu-entry') as Element)
|
||||
})
|
||||
act(() => {
|
||||
userEvent.hover(container.querySelector('#theme') as Element)
|
||||
})
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
|
@ -86,8 +90,12 @@ describe('components/sidebar/SidebarSettingsMenu', () => {
|
|||
)
|
||||
|
||||
const {container} = render(component)
|
||||
userEvent.click(container.querySelector('.menu-entry') as Element)
|
||||
userEvent.hover(container.querySelector('#lang') as Element)
|
||||
act(() => {
|
||||
userEvent.click(container.querySelector('.menu-entry') as Element)
|
||||
})
|
||||
act(() => {
|
||||
userEvent.hover(container.querySelector('#lang') as Element)
|
||||
})
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
|
@ -100,8 +108,12 @@ describe('components/sidebar/SidebarSettingsMenu', () => {
|
|||
)
|
||||
|
||||
const {container} = render(component)
|
||||
userEvent.click(container.querySelector('.menu-entry') as Element)
|
||||
userEvent.hover(container.querySelector('#import') as Element)
|
||||
act(() => {
|
||||
userEvent.click(container.querySelector('.menu-entry') as Element)
|
||||
})
|
||||
act(() => {
|
||||
userEvent.hover(container.querySelector('#import') as Element)
|
||||
})
|
||||
expect(container).toMatchSnapshot()
|
||||
|
||||
userEvent.click(container.querySelector('[aria-label="Asana"]') as Element)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// See LICENSE.txt for license information.
|
||||
import {render} from '@testing-library/react'
|
||||
import React from 'react'
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {wrapDNDIntl} from '../testUtils'
|
||||
import {Constants} from '../constants'
|
||||
|
|
|
@ -7,7 +7,7 @@ import {Provider as ReduxProvider} from 'react-redux'
|
|||
import '@testing-library/jest-dom'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {wrapIntl, mockStateStore} from '../../testUtils'
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import React from 'react'
|
|||
import {render, screen} from '@testing-library/react'
|
||||
import {Provider as ReduxProvider} from 'react-redux'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
import '@testing-library/jest-dom'
|
||||
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
|
|
@ -8,7 +8,7 @@ import {Provider as ReduxProvider} from 'react-redux'
|
|||
import '@testing-library/jest-dom'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {FilterClause} from '../../blocks/filterClause'
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import {Provider as ReduxProvider} from 'react-redux'
|
|||
import '@testing-library/jest-dom'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {FilterClause} from '../../blocks/filterClause'
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import {Provider as ReduxProvider} from 'react-redux'
|
|||
import '@testing-library/jest-dom'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {wrapIntl, mockStateStore} from '../../testUtils'
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import {Provider as ReduxProvider} from 'react-redux'
|
|||
import '@testing-library/jest-dom'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {TestBlockFactory} from '../../test/testBlockFactory'
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import {Provider as ReduxProvider} from 'react-redux'
|
|||
|
||||
import '@testing-library/jest-dom'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {MockStoreEnhanced} from 'redux-mock-store'
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import {Provider as ReduxProvider} from 'react-redux'
|
|||
import '@testing-library/jest-dom'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {BoardView} from '../../blocks/boardView'
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import {Provider as ReduxProvider} from 'react-redux'
|
|||
import '@testing-library/jest-dom'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {wrapIntl, mockStateStore} from '../../testUtils'
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import userEvent from '@testing-library/user-event'
|
|||
|
||||
import React from 'react'
|
||||
import {Provider as ReduxProvider} from 'react-redux'
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import mutator from '../mutator'
|
||||
import {Utils} from '../utils'
|
||||
|
|
|
@ -4,7 +4,7 @@ import {act, render, waitFor} from '@testing-library/react'
|
|||
import React from 'react'
|
||||
import {Provider as ReduxProvider} from 'react-redux'
|
||||
import {MemoryRouter} from 'react-router-dom'
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
|
@ -449,15 +449,15 @@ describe('src/components/workspace', () => {
|
|||
<Workspace readonly={false}/>
|
||||
</ReduxProvider>,
|
||||
), {wrapper: MemoryRouter})
|
||||
jest.runOnlyPendingTimers()
|
||||
})
|
||||
|
||||
await waitFor(() => {
|
||||
const elements = document.querySelectorAll('.AddViewTourStep')
|
||||
expect(elements).toBeDefined()
|
||||
expect(elements.length).toBe(2)
|
||||
expect(elements[1]).toMatchSnapshot()
|
||||
})
|
||||
jest.runOnlyPendingTimers()
|
||||
|
||||
await waitFor(() => expect(document.querySelectorAll('.AddViewTourStep')).toBeDefined(), {timeout: 5000})
|
||||
|
||||
const elements = document.querySelectorAll('.AddViewTourStep')
|
||||
expect(elements.length).toBe(2)
|
||||
expect(elements[1]).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('show copy link tooltip', async () => {
|
||||
|
|
|
@ -14,7 +14,7 @@ import userEvent from '@testing-library/user-event'
|
|||
|
||||
import configureStore from 'redux-mock-store'
|
||||
|
||||
import {mocked} from 'ts-jest/utils'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import thunk from 'redux-thunk'
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ export function getCard(cardId: string): (state: RootState) => Card|undefined {
|
|||
}
|
||||
|
||||
export const getCurrentBoardCards = createSelector(
|
||||
(state) => state.boards.current,
|
||||
(state: RootState) => state.boards.current,
|
||||
getCards,
|
||||
(boardId, cards) => {
|
||||
return Object.values(cards).filter((c) => c.boardId === boardId) as Card[]
|
||||
|
@ -117,7 +117,7 @@ export const getCurrentBoardCards = createSelector(
|
|||
)
|
||||
|
||||
export const getCurrentBoardTemplates = createSelector(
|
||||
(state) => state.boards.current,
|
||||
(state: RootState) => state.boards.current,
|
||||
getTemplates,
|
||||
(boardId, templates) => {
|
||||
return Object.values(templates).filter((c) => c.boardId === boardId) as Card[]
|
||||
|
|
|
@ -90,8 +90,8 @@ export const getContents = createSelector(
|
|||
|
||||
export function getCardContents(cardId: string): (state: RootState) => Array<ContentBlock|ContentBlock[]> {
|
||||
return createSelector(
|
||||
(state) => (state.contents?.contentsByCard && state.contents.contentsByCard[cardId]) || [],
|
||||
(state) => getCards(state)[cardId]?.fields?.contentOrder || getTemplates(state)[cardId]?.fields?.contentOrder,
|
||||
(state: RootState) => (state.contents?.contentsByCard && state.contents.contentsByCard[cardId]) || [],
|
||||
(state: RootState) => getCards(state)[cardId]?.fields?.contentOrder || getTemplates(state)[cardId]?.fields?.contentOrder,
|
||||
(contents, contentOrder): Array<ContentBlock|ContentBlock[]> => {
|
||||
const result: Array<ContentBlock|ContentBlock[]> = []
|
||||
if (!contents) {
|
||||
|
|
|
@ -129,7 +129,7 @@ export function getView(viewId: string): (state: RootState) => BoardView|null {
|
|||
}
|
||||
|
||||
export const getCurrentBoardViews = createSelector(
|
||||
(state) => state.boards.current,
|
||||
(state: RootState) => state.boards.current,
|
||||
getViews,
|
||||
(boardId, views) => {
|
||||
Utils.log(`getCurrentBoardViews boardId: ${boardId} views: ${views.length}`)
|
||||
|
|
|
@ -68,19 +68,10 @@ function makeCommonConfig() {
|
|||
},
|
||||
{
|
||||
test: /\.(eot|tiff|svg|woff2|woff|ttf|png|jpg|jpeg|gif)$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[name].[ext]',
|
||||
outputPath: 'static',
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'image-webpack-loader',
|
||||
options: {},
|
||||
},
|
||||
],
|
||||
type: 'asset/resource',
|
||||
generator: {
|
||||
filename: 'static/[name].[ext]',
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue