Compare commits
14 Commits
pact-stub-
...
aperture/P
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2904168ed4 | ||
|
|
ad80493869 | ||
|
|
a8b803d344 | ||
|
|
0340b94add | ||
|
|
b665d3897b | ||
|
|
542fa3d5ce | ||
|
|
d5949f55c2 | ||
|
|
cd28310937 | ||
|
|
b75347ad06 | ||
|
|
bd931338d8 | ||
|
|
f03d5afa0d | ||
|
|
910e17f75d | ||
|
|
2fa5cadf22 | ||
|
|
bd8221997e |
@@ -28,4 +28,3 @@ APP_ID=''
|
||||
MFE_CONFIG_API_URL=''
|
||||
SEARCH_CATALOG_URL='http://localhost:18000/courses'
|
||||
ENABLE_SKILLS_BUILDER_PROFILE=''
|
||||
ENABLE_PACT_STUBS=true
|
||||
|
||||
2
Makefile
2
Makefile
@@ -7,7 +7,7 @@ transifex_utils = ./node_modules/.bin/transifex-utils.js
|
||||
i18n = ./src/i18n
|
||||
transifex_input = $(i18n)/transifex_input.json
|
||||
# This directory must match .babelrc .
|
||||
transifex_temp = ./temp/babel-plugin-react-intl
|
||||
transifex_temp = ./temp/babel-plugin-formatjs
|
||||
|
||||
NPM_TESTS=build i18n_extract lint test
|
||||
|
||||
|
||||
36
README.rst
36
README.rst
@@ -1,5 +1,6 @@
|
||||
#####################
|
||||
frontend-app-profile
|
||||
##########################
|
||||
#####################
|
||||
|
||||
|license-badge| |status-badge| |ci-badge| |codecov-badge|
|
||||
|
||||
@@ -17,8 +18,9 @@ frontend-app-profile
|
||||
:target: https://codecov.io/github/openedx/frontend-app-profile?branch=main
|
||||
:alt: Codecov
|
||||
|
||||
********
|
||||
Purpose
|
||||
=======
|
||||
********
|
||||
|
||||
This is a micro-frontend application responsible for the display and updating of user profiles.
|
||||
|
||||
@@ -26,11 +28,12 @@ When a user views their own profile, they're given fields to edit their full nam
|
||||
|
||||
When a user views someone else's profile, they see all those fields that that user set as public.
|
||||
|
||||
***************
|
||||
Getting Started
|
||||
===============
|
||||
***************
|
||||
|
||||
Devstack Installation
|
||||
---------------------
|
||||
Installation
|
||||
============
|
||||
|
||||
Follow these steps to provision, run, and enable an instance of the
|
||||
Profile MFE for local development via the `devstack`_.
|
||||
@@ -46,13 +49,30 @@ Profile MFE for local development via the `devstack`_.
|
||||
|
||||
.. code-block::
|
||||
|
||||
npm install
|
||||
npm start # The server will run on port 1995
|
||||
1. Clone your new repo:
|
||||
|
||||
``git clone https://github.com/openedx/frontend-app-profile.git``
|
||||
|
||||
2. Use node v18.x.
|
||||
|
||||
The current version of the micro-frontend build scripts support node 18.
|
||||
Using other major versions of node *may* work, but this is unsupported. For
|
||||
convenience, this repository includes an .nvmrc file to help in setting the
|
||||
correct node version via `nvm <https://github.com/nvm-sh/nvm>`_.
|
||||
|
||||
3. Install npm dependencies:
|
||||
|
||||
``cd frontend-app-profile && npm ci``
|
||||
|
||||
4. Start the dev server:
|
||||
|
||||
``npm start``
|
||||
The server will run on port 1995
|
||||
|
||||
Once the dev server is up, visit http://localhost:1995/u/staff.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
=============
|
||||
|
||||
This MFE is configured via node environment variables supplied at build time. See the .env file for the list of required environment variables. Example build syntax with a single environment variable:
|
||||
|
||||
|
||||
881
package-lock.json
generated
881
package-lock.json
generated
@@ -9,9 +9,9 @@
|
||||
"version": "1.0.0-semantically-released",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@edx/brand": "npm:@edx/brand-openedx@1.2.0",
|
||||
"@edx/frontend-component-footer": "12.4.0",
|
||||
"@edx/frontend-component-header": "4.7.1",
|
||||
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
|
||||
"@edx/frontend-component-footer": "12.6.0",
|
||||
"@edx/frontend-component-header": "4.10.1",
|
||||
"@edx/frontend-platform": "5.6.1",
|
||||
"@edx/paragon": "^20.44.0",
|
||||
"@fortawesome/fontawesome-svg-core": "1.2.36",
|
||||
@@ -21,7 +21,7 @@
|
||||
"@fortawesome/react-fontawesome": "0.2.0",
|
||||
"@pact-foundation/pact": "^11.0.2",
|
||||
"classnames": "2.3.2",
|
||||
"core-js": "3.33.0",
|
||||
"core-js": "3.33.3",
|
||||
"history": "5.3.0",
|
||||
"lodash.camelcase": "4.3.0",
|
||||
"lodash.get": "4.4.2",
|
||||
@@ -30,6 +30,7 @@
|
||||
"prop-types": "15.8.1",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"react-error-boundary": "^4.0.11",
|
||||
"react-helmet": "6.1.0",
|
||||
"react-redux": "7.2.9",
|
||||
"react-router": "6.16.0",
|
||||
@@ -44,14 +45,13 @@
|
||||
"universal-cookie": "4.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "17.8.0",
|
||||
"@commitlint/config-angular": "17.8.0",
|
||||
"@commitlint/cli": "17.8.1",
|
||||
"@commitlint/config-angular": "17.8.1",
|
||||
"@edx/browserslist-config": "^1.1.1",
|
||||
"@edx/frontend-build": "12.9.17",
|
||||
"@edx/frontend-build": "13.0.8",
|
||||
"@edx/reactifex": "2.2.0",
|
||||
"@testing-library/react": "12.1.5",
|
||||
"@wojtekmaj/enzyme-adapter-react-17": "0.8.0",
|
||||
"codecov": "3.8.3",
|
||||
"enzyme": "3.11.0",
|
||||
"glob": "10.3.10",
|
||||
"react-test-renderer": "17.0.2",
|
||||
@@ -2109,16 +2109,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/cli": {
|
||||
"version": "17.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.8.0.tgz",
|
||||
"integrity": "sha512-D3LdyZYbiRyAChfJMNlAd9f2P9vNQ7GWbI9gN2o7L5hF07QJDqj4z/pcJF3PjDbJWOaUUXla287RdDmmKqH2WQ==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.8.1.tgz",
|
||||
"integrity": "sha512-ay+WbzQesE0Rv4EQKfNbSMiJJ12KdKTDzIt0tcK4k11FdsWmtwP0Kp1NWMOUswfIWo6Eb7p7Ln721Nx9FLNBjg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@commitlint/format": "^17.4.4",
|
||||
"@commitlint/lint": "^17.8.0",
|
||||
"@commitlint/load": "^17.8.0",
|
||||
"@commitlint/read": "^17.5.1",
|
||||
"@commitlint/types": "^17.4.4",
|
||||
"@commitlint/format": "^17.8.1",
|
||||
"@commitlint/lint": "^17.8.1",
|
||||
"@commitlint/load": "^17.8.1",
|
||||
"@commitlint/read": "^17.8.1",
|
||||
"@commitlint/types": "^17.8.1",
|
||||
"execa": "^5.0.0",
|
||||
"lodash.isfunction": "^3.0.9",
|
||||
"resolve-from": "5.0.0",
|
||||
@@ -2133,33 +2133,33 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/config-angular": {
|
||||
"version": "17.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/config-angular/-/config-angular-17.8.0.tgz",
|
||||
"integrity": "sha512-3Jygi+j6AqbVbzZujQZqQhk1WPF4ipeh8MHcXlHa1humQQ2ROqfWUqdFlAxn9iIE93lbJz/ANGthJ9+k9sG7Zg==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/config-angular/-/config-angular-17.8.1.tgz",
|
||||
"integrity": "sha512-M3gfC2YttKOEDHrtOtCHfoIdF74vUc+ffJHTyU6j+xqlXrc34iOS665r1rRaTgX6CEeUAnNdpWn0zKYZTj27lA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@commitlint/config-angular-type-enum": "^17.4.0"
|
||||
"@commitlint/config-angular-type-enum": "^17.8.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=v14"
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/config-angular-type-enum": {
|
||||
"version": "17.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/config-angular-type-enum/-/config-angular-type-enum-17.4.0.tgz",
|
||||
"integrity": "sha512-qbmfOfVqQHMKfc6CxS0A9b7+EFsOyEBoh4+i8Qa05uk8YhT/zY1CeIXK5V3wwemMDcHUegyL/ZnwCvWD7g8GxA==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/config-angular-type-enum/-/config-angular-type-enum-17.8.1.tgz",
|
||||
"integrity": "sha512-vuIQ9rZckMPRM6I3mWzfWb7TfvE/yHJXNKaR2weuhf+lQEVSZSGQP3LwdXpMcT2QGKE9VAhU/jw0qIE0Z9EbHA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=v14"
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/config-validator": {
|
||||
"version": "17.6.7",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.6.7.tgz",
|
||||
"integrity": "sha512-vJSncmnzwMvpr3lIcm0I8YVVDJTzyjy7NZAeXbTXy+MPUdAr9pKyyg7Tx/ebOQ9kqzE6O9WT6jg2164br5UdsQ==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.8.1.tgz",
|
||||
"integrity": "sha512-UUgUC+sNiiMwkyiuIFR7JG2cfd9t/7MV8VB4TZ+q02ZFkHoduUS4tJGsCBWvBOGD9Btev6IecPMvlWUfJorkEA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@commitlint/types": "^17.4.4",
|
||||
"@commitlint/types": "^17.8.1",
|
||||
"ajv": "^8.11.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -2167,12 +2167,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/ensure": {
|
||||
"version": "17.6.7",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.6.7.tgz",
|
||||
"integrity": "sha512-mfDJOd1/O/eIb/h4qwXzUxkmskXDL9vNPnZ4AKYKiZALz4vHzwMxBSYtyL2mUIDeU9DRSpEUins8SeKtFkYHSw==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.8.1.tgz",
|
||||
"integrity": "sha512-xjafwKxid8s1K23NFpL8JNo6JnY/ysetKo8kegVM7c8vs+kWLP8VrQq+NbhgVlmCojhEDbzQKp4eRXSjVOGsow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@commitlint/types": "^17.4.4",
|
||||
"@commitlint/types": "^17.8.1",
|
||||
"lodash.camelcase": "^4.3.0",
|
||||
"lodash.kebabcase": "^4.1.1",
|
||||
"lodash.snakecase": "^4.1.1",
|
||||
@@ -2184,21 +2184,21 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/execute-rule": {
|
||||
"version": "17.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz",
|
||||
"integrity": "sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.8.1.tgz",
|
||||
"integrity": "sha512-JHVupQeSdNI6xzA9SqMF+p/JjrHTcrJdI02PwesQIDCIGUrv04hicJgCcws5nzaoZbROapPs0s6zeVHoxpMwFQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=v14"
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/format": {
|
||||
"version": "17.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.4.4.tgz",
|
||||
"integrity": "sha512-+IS7vpC4Gd/x+uyQPTAt3hXs5NxnkqAZ3aqrHd5Bx/R9skyCAWusNlNbw3InDbAK6j166D9asQM8fnmYIa+CXQ==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.8.1.tgz",
|
||||
"integrity": "sha512-f3oMTyZ84M9ht7fb93wbCKmWxO5/kKSbwuYvS867duVomoOsgrgljkGGIztmT/srZnaiGbaK8+Wf8Ik2tSr5eg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@commitlint/types": "^17.4.4",
|
||||
"@commitlint/types": "^17.8.1",
|
||||
"chalk": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -2206,12 +2206,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/is-ignored": {
|
||||
"version": "17.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.8.0.tgz",
|
||||
"integrity": "sha512-8bR6rxNcWaNprPBdE4ePIOwbxutTQGOsRPYWssX+zjGxnEljzaZSGzFUOMxapYILlf8Tts/O1wPQgG549Rdvdg==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.8.1.tgz",
|
||||
"integrity": "sha512-UshMi4Ltb4ZlNn4F7WtSEugFDZmctzFpmbqvpyxD3la510J+PLcnyhf9chs7EryaRFJMdAKwsEKfNK0jL/QM4g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@commitlint/types": "^17.4.4",
|
||||
"@commitlint/types": "^17.8.1",
|
||||
"semver": "7.5.4"
|
||||
},
|
||||
"engines": {
|
||||
@@ -2219,30 +2219,30 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/lint": {
|
||||
"version": "17.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.8.0.tgz",
|
||||
"integrity": "sha512-4ihwnqOY4TcJN6iz5Jv1LeYavvBllONwFyGxOIWmCT5s4PNMb43cws2TUdbXTZL1Vq59etGKd5LWYDFPVbs5EA==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.8.1.tgz",
|
||||
"integrity": "sha512-aQUlwIR1/VMv2D4GXSk7PfL5hIaFSfy6hSHV94O8Y27T5q+DlDEgd/cZ4KmVI+MWKzFfCTiTuWqjfRSfdRllCA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@commitlint/is-ignored": "^17.8.0",
|
||||
"@commitlint/parse": "^17.7.0",
|
||||
"@commitlint/rules": "^17.7.0",
|
||||
"@commitlint/types": "^17.4.4"
|
||||
"@commitlint/is-ignored": "^17.8.1",
|
||||
"@commitlint/parse": "^17.8.1",
|
||||
"@commitlint/rules": "^17.8.1",
|
||||
"@commitlint/types": "^17.8.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=v14"
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/load": {
|
||||
"version": "17.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.8.0.tgz",
|
||||
"integrity": "sha512-9VnGXYJCP4tXmR4YrwP8n5oX6T5ZsHfPQq6WuUQOvAI+QsDQMaTGgTRXr7us+xsjz+b+mMBSagogqfUx2aixyw==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.8.1.tgz",
|
||||
"integrity": "sha512-iF4CL7KDFstP1kpVUkT8K2Wl17h2yx9VaR1ztTc8vzByWWcbO/WaKwxsnCOqow9tVAlzPfo1ywk9m2oJ9ucMqA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@commitlint/config-validator": "^17.6.7",
|
||||
"@commitlint/execute-rule": "^17.4.0",
|
||||
"@commitlint/resolve-extends": "^17.6.7",
|
||||
"@commitlint/types": "^17.4.4",
|
||||
"@commitlint/config-validator": "^17.8.1",
|
||||
"@commitlint/execute-rule": "^17.8.1",
|
||||
"@commitlint/resolve-extends": "^17.8.1",
|
||||
"@commitlint/types": "^17.8.1",
|
||||
"@types/node": "20.5.1",
|
||||
"chalk": "^4.1.0",
|
||||
"cosmiconfig": "^8.0.0",
|
||||
@@ -2252,28 +2252,28 @@
|
||||
"lodash.uniq": "^4.5.0",
|
||||
"resolve-from": "^5.0.0",
|
||||
"ts-node": "^10.8.1",
|
||||
"typescript": "^4.6.4 || ^5.0.0"
|
||||
"typescript": "^4.6.4 || ^5.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=v14"
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/message": {
|
||||
"version": "17.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/message/-/message-17.4.2.tgz",
|
||||
"integrity": "sha512-3XMNbzB+3bhKA1hSAWPCQA3lNxR4zaeQAQcHj0Hx5sVdO6ryXtgUBGGv+1ZCLMgAPRixuc6en+iNAzZ4NzAa8Q==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/message/-/message-17.8.1.tgz",
|
||||
"integrity": "sha512-6bYL1GUQsD6bLhTH3QQty8pVFoETfFQlMn2Nzmz3AOLqRVfNNtXBaSY0dhZ0dM6A2MEq4+2d7L/2LP8TjqGRkA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=v14"
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/parse": {
|
||||
"version": "17.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.7.0.tgz",
|
||||
"integrity": "sha512-dIvFNUMCUHqq5Abv80mIEjLVfw8QNuA4DS7OWip4pcK/3h5wggmjVnlwGCDvDChkw2TjK1K6O+tAEV78oxjxag==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.8.1.tgz",
|
||||
"integrity": "sha512-/wLUickTo0rNpQgWwLPavTm7WbwkZoBy3X8PpkUmlSmQJyWQTj0m6bDjiykMaDt41qcUbfeFfaCvXfiR4EGnfw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@commitlint/types": "^17.4.4",
|
||||
"@commitlint/types": "^17.8.1",
|
||||
"conventional-changelog-angular": "^6.0.0",
|
||||
"conventional-commits-parser": "^4.0.0"
|
||||
},
|
||||
@@ -2282,13 +2282,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/read": {
|
||||
"version": "17.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.5.1.tgz",
|
||||
"integrity": "sha512-7IhfvEvB//p9aYW09YVclHbdf1u7g7QhxeYW9ZHSO8Huzp8Rz7m05aCO1mFG7G8M+7yfFnXB5xOmG18brqQIBg==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.8.1.tgz",
|
||||
"integrity": "sha512-Fd55Oaz9irzBESPCdMd8vWWgxsW3OWR99wOntBDHgf9h7Y6OOHjWEdS9Xzen1GFndqgyoaFplQS5y7KZe0kO2w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@commitlint/top-level": "^17.4.0",
|
||||
"@commitlint/types": "^17.4.4",
|
||||
"@commitlint/top-level": "^17.8.1",
|
||||
"@commitlint/types": "^17.8.1",
|
||||
"fs-extra": "^11.0.0",
|
||||
"git-raw-commits": "^2.0.11",
|
||||
"minimist": "^1.2.6"
|
||||
@@ -2298,13 +2298,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/resolve-extends": {
|
||||
"version": "17.6.7",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.6.7.tgz",
|
||||
"integrity": "sha512-PfeoAwLHtbOaC9bGn/FADN156CqkFz6ZKiVDMjuC2N5N0740Ke56rKU7Wxdwya8R8xzLK9vZzHgNbuGhaOVKIg==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.8.1.tgz",
|
||||
"integrity": "sha512-W/ryRoQ0TSVXqJrx5SGkaYuAaE/BUontL1j1HsKckvM6e5ZaG0M9126zcwL6peKSuIetJi7E87PRQF8O86EW0Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@commitlint/config-validator": "^17.6.7",
|
||||
"@commitlint/types": "^17.4.4",
|
||||
"@commitlint/config-validator": "^17.8.1",
|
||||
"@commitlint/types": "^17.8.1",
|
||||
"import-fresh": "^3.0.0",
|
||||
"lodash.mergewith": "^4.6.2",
|
||||
"resolve-from": "^5.0.0",
|
||||
@@ -2315,15 +2315,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/rules": {
|
||||
"version": "17.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.7.0.tgz",
|
||||
"integrity": "sha512-J3qTh0+ilUE5folSaoK91ByOb8XeQjiGcdIdiB/8UT1/Rd1itKo0ju/eQVGyFzgTMYt8HrDJnGTmNWwcMR1rmA==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.8.1.tgz",
|
||||
"integrity": "sha512-2b7OdVbN7MTAt9U0vKOYKCDsOvESVXxQmrvuVUZ0rGFMCrCPJWWP1GJ7f0lAypbDAhaGb8zqtdOr47192LBrIA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@commitlint/ensure": "^17.6.7",
|
||||
"@commitlint/message": "^17.4.2",
|
||||
"@commitlint/to-lines": "^17.4.0",
|
||||
"@commitlint/types": "^17.4.4",
|
||||
"@commitlint/ensure": "^17.8.1",
|
||||
"@commitlint/message": "^17.8.1",
|
||||
"@commitlint/to-lines": "^17.8.1",
|
||||
"@commitlint/types": "^17.8.1",
|
||||
"execa": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -2331,18 +2331,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/to-lines": {
|
||||
"version": "17.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-17.4.0.tgz",
|
||||
"integrity": "sha512-LcIy/6ZZolsfwDUWfN1mJ+co09soSuNASfKEU5sCmgFCvX5iHwRYLiIuoqXzOVDYOy7E7IcHilr/KS0e5T+0Hg==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-17.8.1.tgz",
|
||||
"integrity": "sha512-LE0jb8CuR/mj6xJyrIk8VLz03OEzXFgLdivBytoooKO5xLt5yalc8Ma5guTWobw998sbR3ogDd+2jed03CFmJA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=v14"
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/top-level": {
|
||||
"version": "17.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-17.4.0.tgz",
|
||||
"integrity": "sha512-/1loE/g+dTTQgHnjoCy0AexKAEFyHsR2zRB4NWrZ6lZSMIxAhBJnmCqwao7b4H8888PsfoTBCLBYIw8vGnej8g==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-17.8.1.tgz",
|
||||
"integrity": "sha512-l6+Z6rrNf5p333SHfEte6r+WkOxGlWK4bLuZKbtf/2TXRN+qhrvn1XE63VhD8Oe9oIHQ7F7W1nG2k/TJFhx2yA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"find-up": "^5.0.0"
|
||||
@@ -2352,9 +2352,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/types": {
|
||||
"version": "17.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.4.4.tgz",
|
||||
"integrity": "sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==",
|
||||
"version": "17.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.8.1.tgz",
|
||||
"integrity": "sha512-PXDQXkAmiMEG162Bqdh9ChML/GJZo6vU+7F03ALKDK8zYc6SuAr47LjG7hGYRqUOz+WK0dU7bQ0xzuqFMdxzeQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.0"
|
||||
@@ -2394,9 +2394,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@csstools/cascade-layer-name-parser": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-1.0.4.tgz",
|
||||
"integrity": "sha512-zXMGsJetbLoXe+gjEES07MEGjL0Uy3hMxmnGtVBrRpVKr5KV9OgCB09zr/vLrsEtoVQTgJFewxaU8IYSAE4tjg==",
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-1.0.5.tgz",
|
||||
"integrity": "sha512-v/5ODKNBMfBl0us/WQjlfsvSlYxfZLhNMVIsuCPib2ulTwGKYbKJbwqw671+qH9Y4wvWVnu7LBChvml/wBKjFg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -2411,8 +2411,8 @@
|
||||
"node": "^14 || ^16 || >=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@csstools/css-parser-algorithms": "^2.3.1",
|
||||
"@csstools/css-tokenizer": "^2.2.0"
|
||||
"@csstools/css-parser-algorithms": "^2.3.2",
|
||||
"@csstools/css-tokenizer": "^2.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@csstools/css-parser-algorithms": {
|
||||
@@ -2485,10 +2485,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/brand": {
|
||||
"name": "@edx/brand-openedx",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/brand-openedx/-/brand-openedx-1.2.0.tgz",
|
||||
"integrity": "sha512-r4PDN3rCgDsLovW44ayxoNNHgG5I4Rvss6MG5CrQEX4oW8YhQVEod+jJtwR5vi0mFLN2GIaMlDpd7iIy03VqXg=="
|
||||
"name": "@openedx/brand-openedx",
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/brand-openedx/-/brand-openedx-1.2.3.tgz",
|
||||
"integrity": "sha512-Dn9CtpC8fovh++Xi4NF5NJoeR9yU2yXZnV9IujxIyGd/dn0Phq5t6dzJVfupwq09mpDnzJv7egA8Znz/3ljO+w=="
|
||||
},
|
||||
"node_modules/@edx/browserslist-config": {
|
||||
"version": "1.2.0",
|
||||
@@ -2510,9 +2510,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-build": {
|
||||
"version": "12.9.17",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-build/-/frontend-build-12.9.17.tgz",
|
||||
"integrity": "sha512-P4w/jp456o5EQ5l0WVl4JIRHnC5xbG+M1Ce7xX1JKex4YDN3lmoBuiaguPg3n6CBDsNKEiBr48n4u+ug+5UTCw==",
|
||||
"version": "13.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-build/-/frontend-build-13.0.8.tgz",
|
||||
"integrity": "sha512-TXUoF7BTIHe4h+W4Dt9+Gf8PXnfVJRwLKitEkpYUH5r4kDEJfyKKGYSbizkciGI+9QScbhm2u8Alv2agDXV1TA==",
|
||||
"dependencies": {
|
||||
"@babel/cli": "7.22.5",
|
||||
"@babel/core": "7.22.5",
|
||||
@@ -2524,13 +2524,14 @@
|
||||
"@babel/preset-react": "7.22.5",
|
||||
"@edx/eslint-config": "3.2.0",
|
||||
"@edx/new-relic-source-map-webpack-plugin": "2.1.0",
|
||||
"@formatjs/cli": "^6.0.3",
|
||||
"@fullhuman/postcss-purgecss": "5.0.0",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "0.5.11",
|
||||
"@svgr/webpack": "8.1.0",
|
||||
"autoprefixer": "10.4.16",
|
||||
"babel-jest": "26.6.3",
|
||||
"babel-loader": "9.1.3",
|
||||
"babel-plugin-react-intl": "7.9.4",
|
||||
"babel-plugin-formatjs": "^10.4.0",
|
||||
"babel-plugin-transform-imports": "2.0.0",
|
||||
"babel-polyfill": "6.26.0",
|
||||
"chalk": "4.1.2",
|
||||
@@ -2552,20 +2553,20 @@
|
||||
"image-minimizer-webpack-plugin": "3.8.3",
|
||||
"jest": "26.6.3",
|
||||
"mini-css-extract-plugin": "1.6.2",
|
||||
"postcss": "8.4.30",
|
||||
"postcss-custom-media": "10.0.1",
|
||||
"postcss": "8.4.31",
|
||||
"postcss-custom-media": "10.0.2",
|
||||
"postcss-loader": "7.3.3",
|
||||
"postcss-rtlcss": "4.0.8",
|
||||
"postcss-rtlcss": "4.0.9",
|
||||
"react-dev-utils": "12.0.1",
|
||||
"react-refresh": "0.14.0",
|
||||
"resolve-url-loader": "5.0.0",
|
||||
"sass": "1.65.1",
|
||||
"sass": "1.69.5",
|
||||
"sass-loader": "13.3.2",
|
||||
"sharp": "0.32.6",
|
||||
"source-map-loader": "4.0.1",
|
||||
"style-loader": "3.3.3",
|
||||
"url-loader": "4.1.1",
|
||||
"webpack": "5.88.2",
|
||||
"webpack": "5.89.0",
|
||||
"webpack-bundle-analyzer": "4.9.1",
|
||||
"webpack-cli": "5.1.4",
|
||||
"webpack-dev-server": "4.15.1",
|
||||
@@ -2579,9 +2580,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer": {
|
||||
"version": "12.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-component-footer/-/frontend-component-footer-12.4.0.tgz",
|
||||
"integrity": "sha512-DmAC8eTB4ARYlzBewzxWB3Afn9v8j9nSudqDd6LiXHUYDZ8Z7QPrMfmrmfDHllflVd22NvljmP2hp+WdtjkgMA==",
|
||||
"version": "12.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-component-footer/-/frontend-component-footer-12.6.0.tgz",
|
||||
"integrity": "sha512-s+YwcThkETBcyRji2Zl7CTYebrsqevP0rmTYyycEL952HkpbQ7EY8Ym0wYH2sp/ZnZ9bTyEeWsiQS5l7eMyY1A==",
|
||||
"dependencies": {
|
||||
"@edx/paragon": "^21.3.1",
|
||||
"@fortawesome/fontawesome-svg-core": "6.4.2",
|
||||
@@ -2592,16 +2593,16 @@
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@edx/frontend-platform": "^4.0.0 || ^5.0.0",
|
||||
"@edx/frontend-platform": "^4.0.0 || ^5.0.0 || ^6.0.0",
|
||||
"prop-types": "^15.5.10",
|
||||
"react": "^16.9.0 || ^17.0.0",
|
||||
"react-dom": "^16.9.0 || ^17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@edx/paragon": {
|
||||
"version": "21.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-21.5.3.tgz",
|
||||
"integrity": "sha512-Xyq7gWLb4n8qWMsNBIPV3tZnOK0bBdHyqj8UVOrFbpBCSPlOES06qpcpT4IrtpfCh0LmUCBiIk5j9XMz3p6zaw==",
|
||||
"version": "21.5.6",
|
||||
"resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-21.5.6.tgz",
|
||||
"integrity": "sha512-CWR9mFBQAnZ29GeP8igPk3dBLgIQmZJ6tZQiou6855TjHIXcvgmbIvtchKw9SgzhW+D5B0hQJet94zsm+GG/Rg==",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^6.1.1",
|
||||
"@fortawesome/react-fontawesome": "^0.1.18",
|
||||
@@ -2748,32 +2749,32 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-header": {
|
||||
"version": "4.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-component-header/-/frontend-component-header-4.7.1.tgz",
|
||||
"integrity": "sha512-Fs4KXXgLBLjI6fH+AxpCyS2ItoGAtbWQ6J1GqK9MeoUsEFHBzL4//fBTbU2HwCJSpn7W8p63CYtk2EOy3eY1Og==",
|
||||
"version": "4.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-component-header/-/frontend-component-header-4.10.1.tgz",
|
||||
"integrity": "sha512-bcQ+ebdy/lM2TfLVB+WhdWNsuc51cFVgt5UQuJcV5nw6ACYUkBVTLbGDT7J8797bsQe6Lywg7Cj9ykB+Dy78Kw==",
|
||||
"dependencies": {
|
||||
"@edx/paragon": "21.3.1",
|
||||
"@edx/paragon": "21.5.6",
|
||||
"@fortawesome/fontawesome-svg-core": "6.4.2",
|
||||
"@fortawesome/free-brands-svg-icons": "6.4.2",
|
||||
"@fortawesome/free-regular-svg-icons": "6.4.2",
|
||||
"@fortawesome/free-solid-svg-icons": "6.4.2",
|
||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||
"axios-mock-adapter": "1.21.5",
|
||||
"axios-mock-adapter": "1.22.0",
|
||||
"babel-polyfill": "6.26.0",
|
||||
"react-responsive": "8.2.0",
|
||||
"react-transition-group": "4.4.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@edx/frontend-platform": "^4.0.0 || ^5.0.0",
|
||||
"@edx/frontend-platform": "^4.0.0 || ^5.0.0 || ^6.0.0",
|
||||
"prop-types": "^15.5.10",
|
||||
"react": "^16.9.0 || ^17.0.0",
|
||||
"react-dom": "^16.9.0 || ^17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-header/node_modules/@edx/paragon": {
|
||||
"version": "21.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-21.3.1.tgz",
|
||||
"integrity": "sha512-bXTUaOEmT8XLnDQzYS8QLMvWK5K2BN4jHlx25lO8N0XWRQeDiQTdbx8OrEbv8QOPTlrv0an5MZc+qjlleJFObg==",
|
||||
"version": "21.5.6",
|
||||
"resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-21.5.6.tgz",
|
||||
"integrity": "sha512-CWR9mFBQAnZ29GeP8igPk3dBLgIQmZJ6tZQiou6855TjHIXcvgmbIvtchKw9SgzhW+D5B0hQJet94zsm+GG/Rg==",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^6.1.1",
|
||||
"@fortawesome/react-fontawesome": "^0.1.18",
|
||||
@@ -3261,6 +3262,25 @@
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/cli": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/cli/-/cli-6.2.0.tgz",
|
||||
"integrity": "sha512-sP04UpocRHYwSovUnunAZHYvCTVbNcaLtWKnr1lETGRUnRRQqnXy/3d2Ce271ELXmNUSde2eHRdu4rv2XaVaiQ==",
|
||||
"bin": {
|
||||
"formatjs": "bin/formatjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.3.4"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"vue": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/ecma402-abstract": {
|
||||
"version": "1.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz",
|
||||
@@ -3347,23 +3367,6 @@
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/intl-numberformat": {
|
||||
"version": "5.7.6",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/intl-numberformat/-/intl-numberformat-5.7.6.tgz",
|
||||
"integrity": "sha512-ZlZfYtvbVHYZY5OG3RXizoCwxKxEKOrzEe2YOw9wbzoxF3PmFn0SAgojCFGLyNXkkR6xVxlylhbuOPf1dkIVNg==",
|
||||
"dependencies": {
|
||||
"@formatjs/ecma402-abstract": "1.4.0",
|
||||
"tslib": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/intl-numberformat/node_modules/@formatjs/ecma402-abstract": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.4.0.tgz",
|
||||
"integrity": "sha512-Mv027hcLFjE45K8UJ8PjRpdDGfR0aManEFj1KzoN8zXNveHGEygpZGfFf/FTTMl+QEVSrPAUlyxaCApvmv47AQ==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/intl-pluralrules": {
|
||||
"version": "4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/intl-pluralrules/-/intl-pluralrules-4.3.3.tgz",
|
||||
@@ -3384,42 +3387,6 @@
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/ts-transformer": {
|
||||
"version": "2.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/ts-transformer/-/ts-transformer-2.13.0.tgz",
|
||||
"integrity": "sha512-mu7sHXZk1NWZrQ3eUqugpSYo8x5/tXkrI4uIbFqCEC0eNgQaIcoKgVeDFgDAcgG+cEme2atAUYSFF+DFWC4org==",
|
||||
"dependencies": {
|
||||
"intl-messageformat-parser": "6.1.2",
|
||||
"tslib": "^2.0.1",
|
||||
"typescript": "^4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"ts-jest": "^26.4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"ts-jest": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/ts-transformer/node_modules/@formatjs/ecma402-abstract": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.5.0.tgz",
|
||||
"integrity": "sha512-wXv36yo+mfWllweN0Fq7sUs7PUiNopn7I0JpLTe3hGu6ZMR4CV7LqK1llhB18pndwpKoafQKb1et2DCJAOW20Q==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/ts-transformer/node_modules/intl-messageformat-parser": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-6.1.2.tgz",
|
||||
"integrity": "sha512-4GQDEPhl/ZMNDKwMsLqyw1LG2IAWjmLJXdmnRcHKeLQzpgtNYZI6lVw1279pqIkRk2MfKb9aDsVFzm565azK5A==",
|
||||
"deprecated": "We've written a new parser that's 6x faster and is backwards compatible. Please use @formatjs/icu-messageformat-parser",
|
||||
"dependencies": {
|
||||
"@formatjs/ecma402-abstract": "1.5.0",
|
||||
"tslib": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@fortawesome/fontawesome-common-types": {
|
||||
"version": "0.2.36",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz",
|
||||
@@ -5071,11 +5038,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@restart/hooks": {
|
||||
"version": "0.4.9",
|
||||
"resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.9.tgz",
|
||||
"integrity": "sha512-3BekqcwB6Umeya+16XPooARn4qEPW6vNvwYnlofIYe6h9qG1/VeD7UvShCWx11eFz5ELYmwIEshz+MkPX3wjcQ==",
|
||||
"version": "0.4.11",
|
||||
"resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz",
|
||||
"integrity": "sha512-Ft/ncTULZN6ldGHiF/k5qt72O8JyRMOeg0tApvCni8LkoiEahO+z3TNxfXIVGy890YtWVDvJAl662dVJSJXvMw==",
|
||||
"dependencies": {
|
||||
"dequal": "^2.0.2"
|
||||
"dequal": "^2.0.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0"
|
||||
@@ -5443,6 +5410,14 @@
|
||||
"@babel/types": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/babel__helper-plugin-utils": {
|
||||
"version": "7.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__helper-plugin-utils/-/babel__helper-plugin-utils-7.10.1.tgz",
|
||||
"integrity": "sha512-6RaT7i6r2rT6ouIDZ2Cd6dPkq4wn1F8pLyDO+7wPVsL1dodvORiZORImaD6j9FBcHjPGuERE0hhtwkuPNXsO0A==",
|
||||
"dependencies": {
|
||||
"@types/babel__core": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/babel__template": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz",
|
||||
@@ -5544,14 +5519,6 @@
|
||||
"@types/send": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/fs-extra": {
|
||||
"version": "9.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
|
||||
"integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
|
||||
@@ -5622,6 +5589,11 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz",
|
||||
"integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA=="
|
||||
},
|
||||
"node_modules/@types/json-stable-stringify": {
|
||||
"version": "1.0.34",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.34.tgz",
|
||||
"integrity": "sha512-s2cfwagOQAS8o06TcwKfr9Wx11dNGbH2E9vJz1cqV+a/LOyhWNLUNd6JSRYNzvB4d29UuJX2M0Dj9vE1T8fRXw=="
|
||||
},
|
||||
"node_modules/@types/json5": {
|
||||
"version": "0.0.29",
|
||||
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||
@@ -5709,9 +5681,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-transition-group": {
|
||||
"version": "4.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz",
|
||||
"integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==",
|
||||
"version": "4.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.7.tgz",
|
||||
"integrity": "sha512-ICCyBl5mvyqYp8Qeq9B5G/fyBSRC0zx3XM3sCC6KkcMsNeAHqXBKkmat4GqdJET5jtYUpZXrxI5flve5qhi2Eg==",
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
@@ -5726,15 +5698,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
|
||||
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ=="
|
||||
},
|
||||
"node_modules/@types/schema-utils": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/schema-utils/-/schema-utils-2.4.0.tgz",
|
||||
"integrity": "sha512-454hrj5gz/FXcUE20ygfEiN4DxZ1sprUo0V1gqIqkNZ/CzoEzAZEll2uxMsuyz6BYjiQan4Aa65xbTemfzW9hQ==",
|
||||
"deprecated": "This is a stub types definition. schema-utils provides its own type definitions, so you do not need this installed.",
|
||||
"dependencies": {
|
||||
"schema-utils": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/send": {
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz",
|
||||
@@ -5775,9 +5738,9 @@
|
||||
"integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw=="
|
||||
},
|
||||
"node_modules/@types/warning": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz",
|
||||
"integrity": "sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA=="
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.1.tgz",
|
||||
"integrity": "sha512-ywJmriP+nvjBKNBEMaNZgj2irZHoxcKeYcyMLbqhYKbDVn8yCIULy2Ol/tvIb37O3IBeZj3RU4tXqQTtGwoAMg=="
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.5.5",
|
||||
@@ -6243,16 +6206,6 @@
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/argv": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz",
|
||||
"integrity": "sha512-dEamhpPEwRUBpLNHeuCm/v+g0anFByHahxodVO/BbAarHVBBg2MccCwf9K+o1Pof+2btdnkJelYVUWjW/VrATw==",
|
||||
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.6.10"
|
||||
}
|
||||
},
|
||||
"node_modules/aria-hidden": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.3.tgz",
|
||||
@@ -6576,9 +6529,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/axios-mock-adapter": {
|
||||
"version": "1.21.5",
|
||||
"resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.21.5.tgz",
|
||||
"integrity": "sha512-5NI1V/VK+8+JeTF8niqOowuysA4b8mGzdlMN/QnTnoXbYh4HZSNiopsDclN2g/m85+G++IrEtUdZaQ3GnaMsSA==",
|
||||
"version": "1.22.0",
|
||||
"resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.22.0.tgz",
|
||||
"integrity": "sha512-dmI0KbkyAhntUR05YY96qg2H6gg0XMl2+qTW0xmYg6Up+BFBAJYRLROMXRdDEL06/Wqwa0TJThAYvFtSFdRCZw==",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"is-buffer": "^2.0.5"
|
||||
@@ -6708,6 +6661,87 @@
|
||||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-formatjs": {
|
||||
"version": "10.5.6",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-formatjs/-/babel-plugin-formatjs-10.5.6.tgz",
|
||||
"integrity": "sha512-XlE8WHF/ZstS5K3ZCWb5nQ6e9u6KpNquTpHpjteGaMSguSjvbfNb7CsF4YHq1fTPBdHWNspA3qfAqMGgHBO4mw==",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.10.4",
|
||||
"@babel/helper-plugin-utils": "^7.10.4",
|
||||
"@babel/plugin-syntax-jsx": "7",
|
||||
"@babel/traverse": "7",
|
||||
"@babel/types": "^7.12.11",
|
||||
"@formatjs/icu-messageformat-parser": "2.6.2",
|
||||
"@formatjs/ts-transformer": "3.13.5",
|
||||
"@types/babel__core": "^7.1.7",
|
||||
"@types/babel__helper-plugin-utils": "^7.10.0",
|
||||
"@types/babel__traverse": "^7.1.7",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-formatjs/node_modules/@formatjs/ecma402-abstract": {
|
||||
"version": "1.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.2.tgz",
|
||||
"integrity": "sha512-k2mTh0m+IV1HRdU0xXM617tSQTi53tVR2muvYOsBeYcUgEAyxV1FOC7Qj279th3fBVQ+Dj6muvNJZcHSPNdbKg==",
|
||||
"dependencies": {
|
||||
"@formatjs/intl-localematcher": "0.4.2",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-formatjs/node_modules/@formatjs/icu-messageformat-parser": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.6.2.tgz",
|
||||
"integrity": "sha512-nF/Iww7sc5h+1MBCDRm68qpHTCG4xvGzYs/x9HFcDETSGScaJ1Fcadk5U/NXjXeCtzD+DhN4BAwKFVclHfKMdA==",
|
||||
"dependencies": {
|
||||
"@formatjs/ecma402-abstract": "1.17.2",
|
||||
"@formatjs/icu-skeleton-parser": "1.6.2",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-formatjs/node_modules/@formatjs/icu-skeleton-parser": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.6.2.tgz",
|
||||
"integrity": "sha512-VtB9Slo4ZL6QgtDFJ8Injvscf0xiDd4bIV93SOJTBjUF4xe2nAWOoSjLEtqIG+hlIs1sNrVKAaFo3nuTI4r5ZA==",
|
||||
"dependencies": {
|
||||
"@formatjs/ecma402-abstract": "1.17.2",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-formatjs/node_modules/@formatjs/intl-localematcher": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.4.2.tgz",
|
||||
"integrity": "sha512-BGdtJFmaNJy5An/Zan4OId/yR9Ih1OojFjcduX/xOvq798OgWSyDtd6Qd5jqJXwJs1ipe4Fxu9+cshic5Ox2tA==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-formatjs/node_modules/@formatjs/ts-transformer": {
|
||||
"version": "3.13.5",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/ts-transformer/-/ts-transformer-3.13.5.tgz",
|
||||
"integrity": "sha512-dh2mmZqkId0UeM+FQtmwugpMGvyzTBmXj5LjwD4M5OeSm62tcgkScjqeO/1EetaNS/JkTUBbsFBnHzaDzh3yOw==",
|
||||
"dependencies": {
|
||||
"@formatjs/icu-messageformat-parser": "2.6.2",
|
||||
"@types/json-stable-stringify": "^1.0.32",
|
||||
"@types/node": "14 || 16 || 17",
|
||||
"chalk": "^4.0.0",
|
||||
"json-stable-stringify": "^1.0.1",
|
||||
"tslib": "^2.4.0",
|
||||
"typescript": "^4.7 || 5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"ts-jest": ">=27"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"ts-jest": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-formatjs/node_modules/@types/node": {
|
||||
"version": "17.0.45",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz",
|
||||
"integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw=="
|
||||
},
|
||||
"node_modules/babel-plugin-istanbul": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
|
||||
@@ -6781,83 +6815,6 @@
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-react-intl": {
|
||||
"version": "7.9.4",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-react-intl/-/babel-plugin-react-intl-7.9.4.tgz",
|
||||
"integrity": "sha512-cMKrHEXrw43yT4M89Wbgq8A8N8lffSquj1Piwov/HVukR7jwOw8gf9btXNsQhT27ccyqEwy+M286JQYy0jby2g==",
|
||||
"deprecated": "this package has been renamed to babel-plugin-formatjs",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.9.0",
|
||||
"@babel/helper-plugin-utils": "^7.8.3",
|
||||
"@babel/types": "^7.9.5",
|
||||
"@formatjs/ts-transformer": "^2.6.0",
|
||||
"@types/babel__core": "^7.1.7",
|
||||
"@types/fs-extra": "^9.0.1",
|
||||
"@types/schema-utils": "^2.4.0",
|
||||
"fs-extra": "^9.0.0",
|
||||
"intl-messageformat-parser": "^5.3.7",
|
||||
"schema-utils": "^2.6.6"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-react-intl/node_modules/ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/epoberezkin"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-react-intl/node_modules/ajv-keywords": {
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
|
||||
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
|
||||
"peerDependencies": {
|
||||
"ajv": "^6.9.1"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-react-intl/node_modules/fs-extra": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
|
||||
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
|
||||
"dependencies": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-react-intl/node_modules/json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
|
||||
},
|
||||
"node_modules/babel-plugin-react-intl/node_modules/schema-utils": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
|
||||
"integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.5",
|
||||
"ajv": "^6.12.4",
|
||||
"ajv-keywords": "^3.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-imports": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-imports/-/babel-plugin-transform-imports-2.0.0.tgz",
|
||||
@@ -7344,9 +7301,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001549",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001549.tgz",
|
||||
"integrity": "sha512-qRp48dPYSCYaP+KurZLhDYdVE+yEyht/3NlmcJgVQ2VMGt6JL36ndQ/7rgspdZsJuxDPFIo/OzBT2+GmIJ53BA==",
|
||||
"version": "1.0.30001563",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001563.tgz",
|
||||
"integrity": "sha512-na2WUmOxnwIZtwnFI2CZ/3er0wdNzU7hN+cPYz/z2ajHThnkWjNBOpEPP4n+4r2WPM847JaMotaJE3bnfzjyKw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -7718,26 +7675,6 @@
|
||||
"node": ">= 0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/codecov": {
|
||||
"version": "3.8.3",
|
||||
"resolved": "https://registry.npmjs.org/codecov/-/codecov-3.8.3.tgz",
|
||||
"integrity": "sha512-Y8Hw+V3HgR7V71xWH2vQ9lyS358CbGCldWlJFR0JirqoGtOoas3R3/OclRTvgUYFK29mmJICDPauVKmpqbwhOA==",
|
||||
"deprecated": "https://about.codecov.io/blog/codecov-uploader-deprecation-plan/",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"argv": "0.0.2",
|
||||
"ignore-walk": "3.0.4",
|
||||
"js-yaml": "3.14.1",
|
||||
"teeny-request": "7.1.1",
|
||||
"urlgrey": "1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"codecov": "bin/codecov"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/collect-v8-coverage": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
|
||||
@@ -7986,9 +7923,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/core-js": {
|
||||
"version": "3.33.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.0.tgz",
|
||||
"integrity": "sha512-HoZr92+ZjFEKar5HS6MC776gYslNOKHt75mEBKWKnPeFDpZ6nH5OeF3S6HFT1mUAUZKrzkez05VboaX8myjSuw==",
|
||||
"version": "3.33.3",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.3.tgz",
|
||||
"integrity": "sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw==",
|
||||
"hasInstallScript": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@@ -10220,21 +10157,6 @@
|
||||
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
|
||||
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
|
||||
},
|
||||
"node_modules/fast-url-parser": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz",
|
||||
"integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"punycode": "^1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-url-parser/node_modules/punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fastest-levenshtein": {
|
||||
"version": "1.0.16",
|
||||
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
|
||||
@@ -10357,6 +10279,14 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/filter-obj": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
|
||||
"integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/finalhandler": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
|
||||
@@ -11857,15 +11787,6 @@
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/ignore-walk": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz",
|
||||
"integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"minimatch": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/image-minimizer-webpack-plugin": {
|
||||
"version": "3.8.3",
|
||||
"resolved": "https://registry.npmjs.org/image-minimizer-webpack-plugin/-/image-minimizer-webpack-plugin-3.8.3.tgz",
|
||||
@@ -12083,15 +12004,6 @@
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/intl-messageformat-parser": {
|
||||
"version": "5.5.1",
|
||||
"resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-5.5.1.tgz",
|
||||
"integrity": "sha512-TvB3LqF2VtP6yI6HXlRT5TxX98HKha6hCcrg9dwlPwNaedVNuQA9KgBdtWKgiyakyCTYHQ+KJeFEstNKfZr64w==",
|
||||
"deprecated": "We've written a new parser that's 6x faster and is backwards compatible. Please use @formatjs/icu-messageformat-parser",
|
||||
"dependencies": {
|
||||
"@formatjs/intl-numberformat": "^5.5.2"
|
||||
}
|
||||
},
|
||||
"node_modules/invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
@@ -14628,9 +14540,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jquery": {
|
||||
"version": "3.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.0.tgz",
|
||||
"integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ==",
|
||||
"version": "3.7.1",
|
||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
|
||||
"integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/js-base64": {
|
||||
@@ -14739,6 +14651,17 @@
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
|
||||
},
|
||||
"node_modules/json-stable-stringify": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz",
|
||||
"integrity": "sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==",
|
||||
"dependencies": {
|
||||
"jsonify": "^0.0.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/json-stable-stringify-without-jsonify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
|
||||
@@ -14766,6 +14689,14 @@
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonify": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz",
|
||||
"integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonparse": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
|
||||
@@ -15149,39 +15080,6 @@
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/mailto-link/node_modules/filter-obj": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
|
||||
"integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mailto-link/node_modules/query-string": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-7.0.1.tgz",
|
||||
"integrity": "sha512-uIw3iRvHnk9to1blJCG3BTc+Ro56CBowJXKmNNAm3RulvPBzWLRqKSiiDk+IplJhsydwtuNMHi8UGQFcCLVfkA==",
|
||||
"dependencies": {
|
||||
"decode-uri-component": "^0.2.0",
|
||||
"filter-obj": "^1.1.0",
|
||||
"split-on-first": "^1.0.0",
|
||||
"strict-uri-encode": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/mailto-link/node_modules/split-on-first": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
|
||||
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/make-dir": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
|
||||
@@ -15706,48 +15604,6 @@
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz",
|
||||
"integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA=="
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.11",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz",
|
||||
"integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch/node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/node-fetch/node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/node-fetch/node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-forge": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
|
||||
@@ -15856,9 +15712,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/object-code": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/object-code/-/object-code-1.2.4.tgz",
|
||||
"integrity": "sha512-uGq4ETUuWe+GA586NXEriiaozNuff+YNFXlpD8cVrM1GoiuTZpCABP+bZCWDrvQDoCiSTyiWAFHD/HF/iwhb2w=="
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/object-code/-/object-code-1.3.0.tgz",
|
||||
"integrity": "sha512-PLplgvzuFhSPBuTX/mtaXEnU3c6g7qKflVVQbV9VWEnV/34iKeAX1jeDNCKq1OgGlsnkA/NjldCzTbHxa7Wj4A=="
|
||||
},
|
||||
"node_modules/object-copy": {
|
||||
"version": "0.1.0",
|
||||
@@ -16775,9 +16631,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.30",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.30.tgz",
|
||||
"integrity": "sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==",
|
||||
"version": "8.4.31",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
|
||||
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -16849,9 +16705,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-custom-media": {
|
||||
"version": "10.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-10.0.1.tgz",
|
||||
"integrity": "sha512-fil7cosvzlIAYmZJPtNFcTH0Er7a3GveEK4q5Y/L24eWQHmiw8Fv/E5DMkVpdbNjkGzJxrvowOSt/Il9HZ06VQ==",
|
||||
"version": "10.0.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-10.0.2.tgz",
|
||||
"integrity": "sha512-zcEFNRmDm2fZvTPdI1pIW3W//UruMcLosmMiCdpQnrCsTRzWlKQPYMa1ud9auL0BmrryKK1+JjIGn19K0UjO/w==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -16863,10 +16719,10 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@csstools/cascade-layer-name-parser": "^1.0.4",
|
||||
"@csstools/css-parser-algorithms": "^2.3.1",
|
||||
"@csstools/css-tokenizer": "^2.2.0",
|
||||
"@csstools/media-query-list-parser": "^2.1.4"
|
||||
"@csstools/cascade-layer-name-parser": "^1.0.5",
|
||||
"@csstools/css-parser-algorithms": "^2.3.2",
|
||||
"@csstools/css-tokenizer": "^2.2.1",
|
||||
"@csstools/media-query-list-parser": "^2.1.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14 || ^16 || >=18"
|
||||
@@ -17256,14 +17112,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-rtlcss": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/postcss-rtlcss/-/postcss-rtlcss-4.0.8.tgz",
|
||||
"integrity": "sha512-CR2sY889PHnX6K8rjW9FG4Qvm9UJsIekDakMtEYGH3zgFp9XADMeaKcA0hPOmkClNh0jWbkaPBm0jZ6fHmqkJQ==",
|
||||
"version": "4.0.9",
|
||||
"resolved": "https://registry.npmjs.org/postcss-rtlcss/-/postcss-rtlcss-4.0.9.tgz",
|
||||
"integrity": "sha512-dCNKEf+FgTv+EA3XI8ysg2RnpS5s3/iZmU+9qpCNFxHU/BhK+4hz7jyCsCAfo0CLnDrMPtaQENhwb+EGm1wh7Q==",
|
||||
"dependencies": {
|
||||
"rtlcss": "4.1.0"
|
||||
"rtlcss": "4.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.21"
|
||||
@@ -17573,6 +17429,23 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/query-string": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-7.0.1.tgz",
|
||||
"integrity": "sha512-uIw3iRvHnk9to1blJCG3BTc+Ro56CBowJXKmNNAm3RulvPBzWLRqKSiiDk+IplJhsydwtuNMHi8UGQFcCLVfkA==",
|
||||
"dependencies": {
|
||||
"decode-uri-component": "^0.2.0",
|
||||
"filter-obj": "^1.1.0",
|
||||
"split-on-first": "^1.0.0",
|
||||
"strict-uri-encode": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/querystringify": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
||||
@@ -17890,6 +17763,17 @@
|
||||
"react": ">= 16.8 || 18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-error-boundary": {
|
||||
"version": "4.0.11",
|
||||
"resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.11.tgz",
|
||||
"integrity": "sha512-U13ul67aP5DOSPNSCWQ/eO0AQEYzEFkVljULQIjMV0KlffTAhxuDoBKdO0pb/JZ8mDhMKFZ9NZi0BmLGUiNphw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-error-overlay": {
|
||||
"version": "6.0.11",
|
||||
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
|
||||
@@ -17901,9 +17785,9 @@
|
||||
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
|
||||
},
|
||||
"node_modules/react-focus-lock": {
|
||||
"version": "2.9.4",
|
||||
"resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.9.4.tgz",
|
||||
"integrity": "sha512-7pEdXyMseqm3kVjhdVH18sovparAzLg5h6WvIx7/Ck3ekjhrrDMEegHSa3swwC8wgfdd7DIdUVRGeiHT9/7Sgg==",
|
||||
"version": "2.9.5",
|
||||
"resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.9.5.tgz",
|
||||
"integrity": "sha512-h6vrdgUbsH2HeD5I7I3Cx1PPrmwGuKYICS+kB9m+32X/9xHRrAbxgvaBpG7BFBN9h3tO+C3qX1QAVESmi4CiIA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.0.0",
|
||||
"focus-lock": "^0.11.6",
|
||||
@@ -17923,12 +17807,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-focus-on": {
|
||||
"version": "3.8.1",
|
||||
"resolved": "https://registry.npmjs.org/react-focus-on/-/react-focus-on-3.8.1.tgz",
|
||||
"integrity": "sha512-fQcBx+SZMgXoRL+69r5+ic4bdVgqaCeKeoFPra8yhcSuL/3unWavfdirEFBGgH71K+RiocMTS6DETHcX0SlOZg==",
|
||||
"version": "3.9.1",
|
||||
"resolved": "https://registry.npmjs.org/react-focus-on/-/react-focus-on-3.9.1.tgz",
|
||||
"integrity": "sha512-IYo2j4mgNpZEJNv+/XzZs3S3xhJbR+AFop092h4OMW7sbFpIMVWxp/Z61V/gfpsgOi7VnoSFXP2bfOWWkjjtOw==",
|
||||
"dependencies": {
|
||||
"aria-hidden": "^1.2.2",
|
||||
"react-focus-lock": "^2.9.2",
|
||||
"react-focus-lock": "^2.9.4",
|
||||
"react-remove-scroll": "^2.5.6",
|
||||
"react-style-singleton": "^2.2.0",
|
||||
"tslib": "^2.3.1",
|
||||
@@ -18914,9 +18798,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rtlcss": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.1.0.tgz",
|
||||
"integrity": "sha512-W+N4hh0nVqVrrn3mRkHakxpB+c9cQ4CRT67O39kgA+1DjyhrdsqyCqIuHXyvWaXn4/835n+oX3fYJCi4+G/06A==",
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.1.1.tgz",
|
||||
"integrity": "sha512-/oVHgBtnPNcggP2aVXQjSy6N1mMAfHg4GSag0QtZBlD5bdDgAHwr4pydqJGd+SUCu9260+Pjqbjwtvu7EMH1KQ==",
|
||||
"dependencies": {
|
||||
"escalade": "^3.1.1",
|
||||
"picocolors": "^1.0.0",
|
||||
@@ -19294,9 +19178,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/sass": {
|
||||
"version": "1.65.1",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.65.1.tgz",
|
||||
"integrity": "sha512-9DINwtHmA41SEd36eVPQ9BJKpn7eKDQmUHmpI0y5Zv2Rcorrh0zS+cFrt050hdNbmmCNKTW3hV5mWfuegNRsEA==",
|
||||
"version": "1.69.5",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.69.5.tgz",
|
||||
"integrity": "sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==",
|
||||
"dependencies": {
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
"immutable": "^4.0.0",
|
||||
@@ -20181,6 +20065,14 @@
|
||||
"wbuf": "^1.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/split-on-first": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
|
||||
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/split-string": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
|
||||
@@ -20326,15 +20218,6 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/stream-events": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz",
|
||||
"integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"stubs": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/streamx": {
|
||||
"version": "2.15.0",
|
||||
"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.0.tgz",
|
||||
@@ -20542,12 +20425,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/stubs": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz",
|
||||
"integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/style-loader": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.3.tgz",
|
||||
@@ -20766,31 +20643,6 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/teeny-request": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.1.tgz",
|
||||
"integrity": "sha512-iwY6rkW5DDGq8hE2YgNQlKbptYpY5Nn2xecjQiNjOXWbKzPGUfmeUBCSQbbr306d7Z7U2N0TPl+/SwYRfua1Dg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"http-proxy-agent": "^4.0.0",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"stream-events": "^1.0.5",
|
||||
"uuid": "^8.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/teeny-request/node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/terminal-link": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
|
||||
@@ -21551,15 +21403,6 @@
|
||||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/urlgrey": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-1.0.0.tgz",
|
||||
"integrity": "sha512-hJfIzMPJmI9IlLkby8QrsCykQ+SXDeO2W5Q9QTW3QpqZVTx4a/K7p8/5q+/isD8vsbVaFgql/gvAoQCRQ2Cb5w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fast-url-parser": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/use": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
|
||||
@@ -21628,9 +21471,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
|
||||
"integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
@@ -21749,9 +21596,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/webpack": {
|
||||
"version": "5.88.2",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz",
|
||||
"integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==",
|
||||
"version": "5.89.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz",
|
||||
"integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==",
|
||||
"dependencies": {
|
||||
"@types/eslint-scope": "^3.7.3",
|
||||
"@types/estree": "^1.0.0",
|
||||
|
||||
20
package.json
20
package.json
@@ -10,12 +10,12 @@
|
||||
},
|
||||
"scripts": {
|
||||
"build": "fedx-scripts webpack",
|
||||
"i18n_extract": "BABEL_ENV=i18n fedx-scripts babel src --quiet > /dev/null",
|
||||
"i18n_extract": "fedx-scripts formatjs extract",
|
||||
"lint": "fedx-scripts eslint --ext .js --ext .jsx .",
|
||||
"snapshot": "fedx-scripts jest --updateSnapshot",
|
||||
"start": "fedx-scripts webpack-dev-server --progress",
|
||||
"test": "TZ=UTC fedx-scripts jest --coverage --passWithNoTests",
|
||||
"stubs": "pact-stub-service ./src/pacts/frontend-app-profile-edx-platform.json --port 18000 --cors"
|
||||
"stubs": "pact-stub-service ./src/pacts/frontend-app-profile-edx-platform.json --port 18000"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/openedx/frontend-app-profile/issues"
|
||||
@@ -28,9 +28,9 @@
|
||||
"extends @edx/browserslist-config"
|
||||
],
|
||||
"dependencies": {
|
||||
"@edx/brand": "npm:@edx/brand-openedx@1.2.0",
|
||||
"@edx/frontend-component-footer": "12.4.0",
|
||||
"@edx/frontend-component-header": "4.7.1",
|
||||
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
|
||||
"@edx/frontend-component-footer": "12.6.0",
|
||||
"@edx/frontend-component-header": "4.10.1",
|
||||
"@edx/frontend-platform": "5.6.1",
|
||||
"@edx/paragon": "^20.44.0",
|
||||
"@fortawesome/fontawesome-svg-core": "1.2.36",
|
||||
@@ -40,7 +40,7 @@
|
||||
"@fortawesome/react-fontawesome": "0.2.0",
|
||||
"@pact-foundation/pact": "^11.0.2",
|
||||
"classnames": "2.3.2",
|
||||
"core-js": "3.33.0",
|
||||
"core-js": "3.33.3",
|
||||
"history": "5.3.0",
|
||||
"lodash.camelcase": "4.3.0",
|
||||
"lodash.get": "4.4.2",
|
||||
@@ -49,6 +49,7 @@
|
||||
"prop-types": "15.8.1",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"react-error-boundary": "^4.0.11",
|
||||
"react-helmet": "6.1.0",
|
||||
"react-redux": "7.2.9",
|
||||
"react-router": "6.16.0",
|
||||
@@ -63,14 +64,13 @@
|
||||
"universal-cookie": "4.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "17.8.0",
|
||||
"@commitlint/config-angular": "17.8.0",
|
||||
"@commitlint/cli": "17.8.1",
|
||||
"@commitlint/config-angular": "17.8.1",
|
||||
"@edx/browserslist-config": "^1.1.1",
|
||||
"@edx/frontend-build": "12.9.17",
|
||||
"@edx/frontend-build": "13.0.8",
|
||||
"@edx/reactifex": "2.2.0",
|
||||
"@testing-library/react": "12.1.5",
|
||||
"@wojtekmaj/enzyme-adapter-react-17": "0.8.0",
|
||||
"codecov": "3.8.3",
|
||||
"enzyme": "3.11.0",
|
||||
"glob": "10.3.10",
|
||||
"react-test-renderer": "17.0.2",
|
||||
|
||||
93
plugins/Plugin.jsx
Normal file
93
plugins/Plugin.jsx
Normal file
@@ -0,0 +1,93 @@
|
||||
'use client';
|
||||
|
||||
import React, {
|
||||
useEffect, useMemo, useState,
|
||||
} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import { logError } from '@edx/frontend-platform/logging';
|
||||
import {
|
||||
dispatchMountedEvent, dispatchReadyEvent, dispatchUnmountedEvent, useHostEvent,
|
||||
} from './data/hooks';
|
||||
import { PLUGIN_RESIZE } from './data/constants';
|
||||
|
||||
// see example-plugin-app/src/PluginOne.jsx for example of customizing errorFallback
|
||||
function errorFallbackDefault() {
|
||||
return (
|
||||
<div>
|
||||
<h2>
|
||||
Oops! An error occurred. Please refresh the screen to try again.
|
||||
</h2>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
export default function Plugin({
|
||||
children, className, style, ready, errorFallbackProp,
|
||||
}) {
|
||||
const [dimensions, setDimensions] = useState({
|
||||
width: null,
|
||||
height: null,
|
||||
});
|
||||
|
||||
const finalStyle = useMemo(() => ({
|
||||
...dimensions,
|
||||
...style,
|
||||
}), [dimensions, style]);
|
||||
|
||||
const errorFallback = errorFallbackProp || errorFallbackDefault;
|
||||
|
||||
// Error logging function
|
||||
// Need to confirm: When an error is caught here, the logging will be sent to the child MFE's logging service
|
||||
const logErrorToService = (error, info) => {
|
||||
logError(error, { stack: info.componentStack });
|
||||
};
|
||||
|
||||
useHostEvent(PLUGIN_RESIZE, ({ payload }) => {
|
||||
setDimensions({
|
||||
width: payload.width,
|
||||
height: payload.height,
|
||||
});
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
dispatchMountedEvent();
|
||||
|
||||
return () => {
|
||||
dispatchUnmountedEvent();
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (ready) {
|
||||
dispatchReadyEvent();
|
||||
}
|
||||
}, [ready]);
|
||||
|
||||
return (
|
||||
<div className={className} style={finalStyle}>
|
||||
<ErrorBoundary
|
||||
FallbackComponent={errorFallback}
|
||||
onError={logErrorToService}
|
||||
>
|
||||
{children}
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Plugin.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
className: PropTypes.string,
|
||||
errorFallbackProp: PropTypes.func,
|
||||
ready: PropTypes.bool,
|
||||
style: PropTypes.object, // eslint-disable-line
|
||||
};
|
||||
|
||||
Plugin.defaultProps = {
|
||||
className: null,
|
||||
errorFallbackProp: null,
|
||||
style: {},
|
||||
ready: true,
|
||||
};
|
||||
42
plugins/PluginContainer.jsx
Normal file
42
plugins/PluginContainer.jsx
Normal file
@@ -0,0 +1,42 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import PluginContainerIframe from './PluginContainerIframe';
|
||||
|
||||
import {
|
||||
IFRAME_PLUGIN,
|
||||
} from './data/constants';
|
||||
import { pluginConfigShape } from './data/shapes';
|
||||
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
export default function PluginContainer({ config, ...props }) {
|
||||
if (config === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// this will allow for future plugin types to be inserted in the PluginErrorBoundary
|
||||
let renderer = null;
|
||||
switch (config.type) {
|
||||
case IFRAME_PLUGIN:
|
||||
renderer = (
|
||||
<PluginContainerIframe config={config} {...props} />
|
||||
);
|
||||
break;
|
||||
// istanbul ignore next: default isn't meaningful, just satisfying linter
|
||||
default:
|
||||
}
|
||||
|
||||
return (
|
||||
renderer
|
||||
);
|
||||
}
|
||||
|
||||
PluginContainer.propTypes = {
|
||||
config: pluginConfigShape,
|
||||
};
|
||||
|
||||
PluginContainer.defaultProps = {
|
||||
config: null,
|
||||
};
|
||||
99
plugins/PluginContainerIframe.jsx
Normal file
99
plugins/PluginContainerIframe.jsx
Normal file
@@ -0,0 +1,99 @@
|
||||
import React, {
|
||||
useEffect, useState,
|
||||
} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import {
|
||||
PLUGIN_MOUNTED,
|
||||
PLUGIN_READY,
|
||||
PLUGIN_RESIZE,
|
||||
} from './data/constants';
|
||||
import {
|
||||
dispatchPluginEvent,
|
||||
useElementSize,
|
||||
usePluginEvent,
|
||||
} from './data/hooks';
|
||||
import { pluginConfigShape } from './data/shapes';
|
||||
|
||||
/**
|
||||
* Feature policy for iframe, allowing access to certain courseware-related media.
|
||||
*
|
||||
* We must use the wildcard (*) origin for each feature, as courseware content
|
||||
* may be embedded in external iframes. Notably, xblock-lti-consumer is a popular
|
||||
* block that iframes external course content.
|
||||
|
||||
* This policy was selected in conference with the edX Security Working Group.
|
||||
* Changes to it should be vetted by them (security@edx.org).
|
||||
*/
|
||||
export const IFRAME_FEATURE_POLICY = (
|
||||
'fullscreen; microphone *; camera *; midi *; geolocation *; encrypted-media *'
|
||||
);
|
||||
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
export default function PluginContainerIframe({
|
||||
config, fallback, className, ...props
|
||||
}) {
|
||||
const { url } = config;
|
||||
const { title, scrolling } = props;
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const [ready, setReady] = useState(false);
|
||||
|
||||
const [iframeRef, iframeElement, width, height] = useElementSize();
|
||||
|
||||
useEffect(() => {
|
||||
if (mounted) {
|
||||
dispatchPluginEvent(iframeElement, {
|
||||
type: PLUGIN_RESIZE,
|
||||
payload: {
|
||||
width,
|
||||
height,
|
||||
},
|
||||
}, url);
|
||||
}
|
||||
}, [iframeElement, mounted, width, height, url]);
|
||||
|
||||
usePluginEvent(iframeElement, PLUGIN_MOUNTED, () => {
|
||||
setMounted(true);
|
||||
});
|
||||
|
||||
usePluginEvent(iframeElement, PLUGIN_READY, () => {
|
||||
setReady(true);
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<iframe
|
||||
ref={iframeRef}
|
||||
title={title}
|
||||
src={url}
|
||||
allow={IFRAME_FEATURE_POLICY}
|
||||
scrolling={scrolling}
|
||||
referrerPolicy="origin" // The sent referrer will be limited to the origin of the referring page: its scheme, host, and port.
|
||||
className={classNames(
|
||||
'border border-0',
|
||||
{ 'd-none': !ready },
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
{!ready && fallback}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
PluginContainerIframe.propTypes = {
|
||||
config: pluginConfigShape,
|
||||
fallback: PropTypes.node,
|
||||
scrolling: PropTypes.oneOf(['auto', 'yes', 'no']),
|
||||
title: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
PluginContainerIframe.defaultProps = {
|
||||
config: null,
|
||||
fallback: null,
|
||||
scrolling: 'auto',
|
||||
title: null,
|
||||
className: null,
|
||||
};
|
||||
45
plugins/PluginErrorBoundary.jsx
Normal file
45
plugins/PluginErrorBoundary.jsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { logError } from '@edx/frontend-platform/logging';
|
||||
|
||||
export default class PluginErrorBoundary extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { hasError: false };
|
||||
}
|
||||
|
||||
static getDerivedStateFromError() {
|
||||
// Update state so the next render will show the fallback UI.
|
||||
return { hasError: true };
|
||||
}
|
||||
|
||||
componentDidCatch(error, info) {
|
||||
logError(error, { stack: info.componentStack });
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
// You can render any custom fallback UI
|
||||
return (
|
||||
<FormattedMessage
|
||||
id="plugin.load.failure.text"
|
||||
defaultMessage="This content failed to load."
|
||||
description="error message when an unexpected error occurs"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
PluginErrorBoundary.propTypes = {
|
||||
children: PropTypes.node,
|
||||
};
|
||||
|
||||
PluginErrorBoundary.defaultProps = {
|
||||
children: null,
|
||||
};
|
||||
75
plugins/PluginSlot.jsx
Normal file
75
plugins/PluginSlot.jsx
Normal file
@@ -0,0 +1,75 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import React, { forwardRef } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { Spinner } from '@edx/paragon';
|
||||
import PropTypes from 'prop-types';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
|
||||
// import { usePluginSlot } from './data/hooks';
|
||||
import PluginContainer from './PluginContainer';
|
||||
|
||||
const PluginSlot = forwardRef(({
|
||||
as, id, intl, pluginProps, children, ...props
|
||||
}, ref) => {
|
||||
/* the plugins below are obtained by the id passed into PluginSlot by the Host MFE. See example/src/PluginsPage.jsx
|
||||
for an example of how PluginSlot is populated, and example/src/index.jsx for a dummy JS config that holds all plugins
|
||||
*/
|
||||
// const { plugins, keepDefault } = usePluginSlot(id);
|
||||
|
||||
const { fallback } = pluginProps;
|
||||
|
||||
// TODO: Add internationalization to the "Loading" text on the spinner.
|
||||
let finalFallback = (
|
||||
<div className={classNames(pluginProps.className, 'd-flex justify-content-center align-items-center')}>
|
||||
<Spinner animation="border" screenReaderText="Loading" />
|
||||
</div>
|
||||
);
|
||||
if (fallback !== undefined) {
|
||||
finalFallback = fallback;
|
||||
}
|
||||
|
||||
let finalChildren = [];
|
||||
// if (plugins.length > 0) {
|
||||
// if (keepDefault) {
|
||||
// finalChildren.push(children);
|
||||
// }
|
||||
// plugins.forEach((pluginConfig) => {
|
||||
// finalChildren.push(
|
||||
// <PluginContainer
|
||||
// key={pluginConfig.url}
|
||||
// config={pluginConfig}
|
||||
// fallback={finalFallback}
|
||||
// {...pluginProps}
|
||||
// />,
|
||||
// );
|
||||
// });
|
||||
// } else {
|
||||
finalChildren = children;
|
||||
// }
|
||||
|
||||
return React.createElement(
|
||||
as,
|
||||
{
|
||||
...props,
|
||||
ref,
|
||||
},
|
||||
finalChildren,
|
||||
);
|
||||
});
|
||||
|
||||
export default injectIntl(PluginSlot);
|
||||
|
||||
PluginSlot.propTypes = {
|
||||
as: PropTypes.elementType,
|
||||
children: PropTypes.node,
|
||||
id: PropTypes.string.isRequired,
|
||||
intl: intlShape.isRequired,
|
||||
pluginProps: PropTypes.object, // eslint-disable-line
|
||||
};
|
||||
|
||||
PluginSlot.defaultProps = {
|
||||
as: 'div',
|
||||
children: null,
|
||||
pluginProps: {},
|
||||
};
|
||||
8
plugins/data/constants.js
Normal file
8
plugins/data/constants.js
Normal file
@@ -0,0 +1,8 @@
|
||||
// TODO: We expect other plugin types to be added here, such as LTI_PLUGIN and BUILD_TIME_PLUGIN.
|
||||
export const IFRAME_PLUGIN = 'IFRAME_PLUGIN'; // loads iframe at the URL, rather than loading a JS file.
|
||||
|
||||
// Plugin lifecycle events
|
||||
export const PLUGIN_MOUNTED = 'PLUGIN_MOUNTED';
|
||||
export const PLUGIN_READY = 'PLUGIN_READY';
|
||||
export const PLUGIN_UNMOUNTED = 'PLUGIN_UNMOUNTED';
|
||||
export const PLUGIN_RESIZE = 'PLUGIN_RESIZE';
|
||||
96
plugins/data/hooks.js
Normal file
96
plugins/data/hooks.js
Normal file
@@ -0,0 +1,96 @@
|
||||
import {
|
||||
useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState,
|
||||
} from 'react';
|
||||
import { PLUGIN_MOUNTED, PLUGIN_READY, PLUGIN_UNMOUNTED } from './constants';
|
||||
|
||||
export function useMessageEvent(srcWindow, type, callback) {
|
||||
useLayoutEffect(() => {
|
||||
const listener = (event) => {
|
||||
// Filter messages to those from our source window.
|
||||
if (event.source === srcWindow) {
|
||||
if (event.data.type === type) {
|
||||
callback({ type, payload: event.data.payload });
|
||||
}
|
||||
}
|
||||
};
|
||||
if (srcWindow !== null) {
|
||||
global.addEventListener('message', listener);
|
||||
}
|
||||
return () => {
|
||||
global.removeEventListener('message', listener);
|
||||
};
|
||||
}, [srcWindow, type, callback]);
|
||||
}
|
||||
|
||||
export function useHostEvent(type, callback) {
|
||||
useMessageEvent(global.parent, type, callback);
|
||||
}
|
||||
|
||||
export function usePluginEvent(iframeElement, type, callback) {
|
||||
const contentWindow = iframeElement ? iframeElement.contentWindow : null;
|
||||
useMessageEvent(contentWindow, type, callback);
|
||||
}
|
||||
|
||||
export function dispatchMessageEvent(targetWindow, message, targetOrigin) {
|
||||
// Checking targetOrigin falsiness here since '', null or undefined would all be reasons not to
|
||||
// try to post a message to the origin.
|
||||
if (targetOrigin) {
|
||||
targetWindow.postMessage(message, targetOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
export function dispatchPluginEvent(iframeElement, message, targetOrigin) {
|
||||
dispatchMessageEvent(iframeElement.contentWindow, message, targetOrigin);
|
||||
}
|
||||
|
||||
export function dispatchHostEvent(message) {
|
||||
dispatchMessageEvent(global.parent, message, global.document.referrer);
|
||||
}
|
||||
|
||||
export function dispatchReadyEvent() {
|
||||
dispatchHostEvent({ type: PLUGIN_READY });
|
||||
}
|
||||
|
||||
export function dispatchMountedEvent() {
|
||||
dispatchHostEvent({ type: PLUGIN_MOUNTED });
|
||||
}
|
||||
|
||||
export function dispatchUnmountedEvent() {
|
||||
dispatchHostEvent({ type: PLUGIN_UNMOUNTED });
|
||||
}
|
||||
|
||||
export function useElementSize() {
|
||||
const observerRef = useRef();
|
||||
|
||||
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
|
||||
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
||||
|
||||
const [element, setElement] = useState(null);
|
||||
|
||||
const measuredRef = useCallback(_element => {
|
||||
setElement(_element);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
observerRef.current = new ResizeObserver(() => {
|
||||
if (element) {
|
||||
setDimensions({
|
||||
width: element.clientWidth,
|
||||
height: element.clientHeight,
|
||||
});
|
||||
setOffset({
|
||||
x: element.offsetLeft,
|
||||
y: element.offsetTop,
|
||||
});
|
||||
}
|
||||
});
|
||||
if (element) {
|
||||
observerRef.current.observe(element);
|
||||
}
|
||||
}, [element]);
|
||||
|
||||
return useMemo(
|
||||
() => ([measuredRef, element, dimensions.width, dimensions.height, offset.x, offset.y]),
|
||||
[measuredRef, element, dimensions, offset],
|
||||
);
|
||||
}
|
||||
10
plugins/data/shapes.js
Normal file
10
plugins/data/shapes.js
Normal file
@@ -0,0 +1,10 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
import PropTypes from 'prop-types';
|
||||
import { IFRAME_PLUGIN } from './constants';
|
||||
|
||||
export const pluginConfigShape = PropTypes.shape({
|
||||
url: PropTypes.string.isRequired,
|
||||
type: PropTypes.oneOf([IFRAME_PLUGIN]).isRequired,
|
||||
// This is a place for us to put any generic props we want to pass to the component. We need it.
|
||||
props: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
||||
});
|
||||
18
plugins/index.js
Normal file
18
plugins/index.js
Normal file
@@ -0,0 +1,18 @@
|
||||
// export {
|
||||
// usePluginSlot,
|
||||
// } from './data/hooks';
|
||||
export {
|
||||
default as Plugin,
|
||||
} from './Plugin';
|
||||
export {
|
||||
default as PluginContainer,
|
||||
} from './PluginContainer';
|
||||
export {
|
||||
default as PluginSlot,
|
||||
} from './PluginSlot';
|
||||
export {
|
||||
IFRAME_PLUGIN,
|
||||
} from './data/constants';
|
||||
export {
|
||||
default as PluginErrorBoundary,
|
||||
} from './PluginErrorBoundary';
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import Header from '@edx/frontend-component-header';
|
||||
import Footer from '@edx/frontend-component-footer';
|
||||
@@ -27,15 +28,25 @@ import Head from './head/Head';
|
||||
|
||||
import AppRoutes from './routes/AppRoutes';
|
||||
|
||||
const RenderFooter = () => {
|
||||
const location = useLocation();
|
||||
return location.pathname.includes('/plugin') ? null : <Footer />;
|
||||
};
|
||||
|
||||
const RenderHeader = () => {
|
||||
const location = useLocation();
|
||||
return location.pathname.includes('/plugin') ? null : <Header />;
|
||||
};
|
||||
|
||||
subscribe(APP_READY, () => {
|
||||
ReactDOM.render(
|
||||
<AppProvider store={configureStore()}>
|
||||
<Head />
|
||||
<Header />
|
||||
<RenderHeader />
|
||||
<main id="main">
|
||||
<AppRoutes />
|
||||
</main>
|
||||
<Footer />
|
||||
<RenderFooter />
|
||||
</AppProvider>,
|
||||
document.getElementById('root'),
|
||||
);
|
||||
@@ -48,7 +59,6 @@ subscribe(APP_INIT_ERROR, (error) => {
|
||||
initialize({
|
||||
messages,
|
||||
hydrateAuthenticatedUser: true,
|
||||
isPactStubEnabled: process.env.ENABLE_PACT_STUBS,
|
||||
handlers: {
|
||||
config: () => {
|
||||
mergeConfig({
|
||||
|
||||
@@ -57,208 +57,6 @@
|
||||
},
|
||||
"status": 200
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "A request for user's basic information",
|
||||
"providerStates": [
|
||||
{
|
||||
"name": "I have a user's basic information"
|
||||
}
|
||||
],
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"path": "/api/user/v1/accounts/edx"
|
||||
},
|
||||
"response": {
|
||||
"body": {
|
||||
"bio": "This is my bio",
|
||||
"country": "ME",
|
||||
"dateJoined": "2017-06-07T00:44:23Z",
|
||||
"email": "edx@example.com",
|
||||
"isActive": true,
|
||||
"name": "Lemon Seltzer",
|
||||
"username": "edx",
|
||||
"yearOfBirth": 1901,
|
||||
"language_proficiencies": [{"code": "en"}]
|
||||
},
|
||||
"headers": {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
"matchingRules": {
|
||||
"body": {
|
||||
"$": {
|
||||
"combine": "AND",
|
||||
"matchers": [
|
||||
{
|
||||
"match": "type"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": 200
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "A request for user's basic information",
|
||||
"providerStates": [
|
||||
{
|
||||
"name": "I have a user's basic information"
|
||||
}
|
||||
],
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"path": "/login_refresh"
|
||||
},
|
||||
"response": {
|
||||
"body": {
|
||||
"login": "This is my login_refresh"
|
||||
},
|
||||
"headers": {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
"matchingRules": {
|
||||
"body": {
|
||||
"$": {
|
||||
"combine": "AND",
|
||||
"matchers": [
|
||||
{
|
||||
"match": "type"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": 200
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "A request for user's basic information",
|
||||
"providerStates": [
|
||||
{
|
||||
"name": "I have a user's basic information"
|
||||
}
|
||||
],
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"path": "/csrf/api/v1/token"
|
||||
},
|
||||
"response": {
|
||||
"body": {
|
||||
"csrfToken": "UYVGuFndy1sJPtAFtXPNQTnkZxZPKSYbvd3KKoKTyk6Vq9k01lg4vSsgjidWbnpt"
|
||||
},
|
||||
"headers": {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
"matchingRules": {
|
||||
"body": {
|
||||
"$": {
|
||||
"combine": "AND",
|
||||
"matchers": [
|
||||
{
|
||||
"match": "type"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": 200
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "A request for user's basic information",
|
||||
"providerStates": [
|
||||
{
|
||||
"name": "I have a user's basic information"
|
||||
}
|
||||
],
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"path": "/api/user/v1/preferences/edx"
|
||||
},
|
||||
"response": {
|
||||
"body": {
|
||||
"pref-lang": "en"
|
||||
},
|
||||
"headers": {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
"matchingRules": {
|
||||
"body": {
|
||||
"$": {
|
||||
"combine": "AND",
|
||||
"matchers": [
|
||||
{
|
||||
"match": "type"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": 200
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "A request for user's basic information",
|
||||
"providerStates": [
|
||||
{
|
||||
"name": "I have a user's basic information"
|
||||
}
|
||||
],
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"path": "/api/certificates/v0/certificates/edx/"
|
||||
},
|
||||
"response": {
|
||||
"body": [],
|
||||
"headers": {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
"matchingRules": {
|
||||
"body": {
|
||||
"$": {
|
||||
"combine": "AND",
|
||||
"matchers": [
|
||||
{
|
||||
"match": "type"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": 200
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "A request for user's basic information",
|
||||
"providerStates": [
|
||||
{
|
||||
"name": "I have a user's basic information"
|
||||
}
|
||||
],
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"path": "/event"
|
||||
},
|
||||
"response": {
|
||||
"body": [],
|
||||
"headers": {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
"matchingRules": {
|
||||
"body": {
|
||||
"$": {
|
||||
"combine": "AND",
|
||||
"matchers": [
|
||||
{
|
||||
"match": "type"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": 200
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
|
||||
@@ -6,7 +6,6 @@ const DateJoined = ({ date }) => {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<p className="mb-0">
|
||||
<FormattedMessage
|
||||
|
||||
@@ -126,7 +126,7 @@ class ProfilePage extends React.Component {
|
||||
|
||||
return (
|
||||
<span data-hj-suppress>
|
||||
<h1 className="h2 mb-0 font-weight-bold">{this.props.params.username}</h1>
|
||||
<h1 className="h2 mb-0 font-weight-bold text-truncate">{this.props.params.username}</h1>
|
||||
<DateJoined date={dateJoined} />
|
||||
{this.isYOBDisabled() && <UsernameDescription />}
|
||||
<hr className="d-none d-md-block" />
|
||||
@@ -178,6 +178,7 @@ class ProfilePage extends React.Component {
|
||||
visibilityLearningGoal,
|
||||
languageProficiencies,
|
||||
visibilityLanguageProficiencies,
|
||||
courseCertificates,
|
||||
visibilityCourseCertificates,
|
||||
bio,
|
||||
visibilityBio,
|
||||
@@ -196,6 +197,17 @@ class ProfilePage extends React.Component {
|
||||
changeHandler: this.handleChange,
|
||||
};
|
||||
|
||||
const isBlockVisible = (blockInfo) => this.isAuthenticatedUserProfile()
|
||||
|| (!this.isAuthenticatedUserProfile() && Boolean(blockInfo));
|
||||
|
||||
const isLanguageBlockVisible = isBlockVisible(languageProficiencies.length);
|
||||
const isEducationBlockVisible = isBlockVisible(levelOfEducation);
|
||||
const isSocialLinksBLockVisible = isBlockVisible(socialLinks.some((link) => link.socialLink !== null));
|
||||
const isBioBlockVisible = isBlockVisible(bio);
|
||||
const isCertificatesBlockVisible = isBlockVisible(courseCertificates.length);
|
||||
const isNameBlockVisible = isBlockVisible(name);
|
||||
const isLocationBlockVisible = isBlockVisible(country);
|
||||
|
||||
return (
|
||||
<div className="container-fluid">
|
||||
<div className="row align-items-center pt-4 mb-4 pt-md-0 mb-md-0">
|
||||
@@ -212,7 +224,8 @@ class ProfilePage extends React.Component {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col pl-0">
|
||||
<div>PluginPOC</div>
|
||||
<div className="col">
|
||||
<div className="d-md-none">
|
||||
{this.renderHeadingLockup()}
|
||||
</div>
|
||||
@@ -230,46 +243,58 @@ class ProfilePage extends React.Component {
|
||||
<div className="d-md-none mb-4">
|
||||
{this.renderViewMyRecordsButton()}
|
||||
</div>
|
||||
<Name
|
||||
name={name}
|
||||
visibilityName={visibilityName}
|
||||
formId="name"
|
||||
{...commonFormProps}
|
||||
/>
|
||||
<Country
|
||||
country={country}
|
||||
visibilityCountry={visibilityCountry}
|
||||
formId="country"
|
||||
{...commonFormProps}
|
||||
/>
|
||||
<PreferredLanguage
|
||||
languageProficiencies={languageProficiencies}
|
||||
visibilityLanguageProficiencies={visibilityLanguageProficiencies}
|
||||
formId="languageProficiencies"
|
||||
{...commonFormProps}
|
||||
/>
|
||||
<Education
|
||||
levelOfEducation={levelOfEducation}
|
||||
visibilityLevelOfEducation={visibilityLevelOfEducation}
|
||||
formId="levelOfEducation"
|
||||
{...commonFormProps}
|
||||
/>
|
||||
<SocialLinks
|
||||
socialLinks={socialLinks}
|
||||
draftSocialLinksByPlatform={draftSocialLinksByPlatform}
|
||||
visibilitySocialLinks={visibilitySocialLinks}
|
||||
formId="socialLinks"
|
||||
{...commonFormProps}
|
||||
/>
|
||||
{isNameBlockVisible && (
|
||||
<Name
|
||||
name={name}
|
||||
visibilityName={visibilityName}
|
||||
formId="name"
|
||||
{...commonFormProps}
|
||||
/>
|
||||
)}
|
||||
{isLocationBlockVisible && (
|
||||
<Country
|
||||
country={country}
|
||||
visibilityCountry={visibilityCountry}
|
||||
formId="country"
|
||||
{...commonFormProps}
|
||||
/>
|
||||
)}
|
||||
{isLanguageBlockVisible && (
|
||||
<PreferredLanguage
|
||||
languageProficiencies={languageProficiencies}
|
||||
visibilityLanguageProficiencies={visibilityLanguageProficiencies}
|
||||
formId="languageProficiencies"
|
||||
{...commonFormProps}
|
||||
/>
|
||||
)}
|
||||
{isEducationBlockVisible && (
|
||||
<Education
|
||||
levelOfEducation={levelOfEducation}
|
||||
visibilityLevelOfEducation={visibilityLevelOfEducation}
|
||||
formId="levelOfEducation"
|
||||
{...commonFormProps}
|
||||
/>
|
||||
)}
|
||||
{isSocialLinksBLockVisible && (
|
||||
<SocialLinks
|
||||
socialLinks={socialLinks}
|
||||
draftSocialLinksByPlatform={draftSocialLinksByPlatform}
|
||||
visibilitySocialLinks={visibilitySocialLinks}
|
||||
formId="socialLinks"
|
||||
{...commonFormProps}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="pt-md-3 col-md-8 col-lg-7 offset-lg-1">
|
||||
{!this.isYOBDisabled() && this.renderAgeMessage()}
|
||||
<Bio
|
||||
bio={bio}
|
||||
visibilityBio={visibilityBio}
|
||||
formId="bio"
|
||||
{...commonFormProps}
|
||||
/>
|
||||
{isBioBlockVisible && (
|
||||
<Bio
|
||||
bio={bio}
|
||||
visibilityBio={visibilityBio}
|
||||
formId="bio"
|
||||
{...commonFormProps}
|
||||
/>
|
||||
)}
|
||||
{getConfig().ENABLE_SKILLS_BUILDER_PROFILE && (
|
||||
<LearningGoal
|
||||
learningGoal={learningGoal}
|
||||
@@ -278,11 +303,13 @@ class ProfilePage extends React.Component {
|
||||
{...commonFormProps}
|
||||
/>
|
||||
)}
|
||||
<Certificates
|
||||
visibilityCourseCertificates={visibilityCourseCertificates}
|
||||
formId="certificates"
|
||||
{...commonFormProps}
|
||||
/>
|
||||
{isCertificatesBlockVisible && (
|
||||
<Certificates
|
||||
visibilityCourseCertificates={visibilityCourseCertificates}
|
||||
formId="certificates"
|
||||
{...commonFormProps}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -114,16 +114,34 @@ describe('<ProfilePage />', () => {
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('viewing other profile', () => {
|
||||
it('viewing other profile with all fields', () => {
|
||||
const contextValue = {
|
||||
authenticatedUser: { userId: 123, username: 'staff', administrator: true },
|
||||
config: getConfig(),
|
||||
};
|
||||
|
||||
const component = (
|
||||
<ProfilePageWrapper
|
||||
contextValue={contextValue}
|
||||
store={mockStore(storeMocks.viewOtherProfile)}
|
||||
params={{ username: 'verified' }} // Override default params
|
||||
store={mockStore({
|
||||
...storeMocks.viewOtherProfile,
|
||||
profilePage: {
|
||||
...storeMocks.viewOtherProfile.profilePage,
|
||||
account: {
|
||||
...storeMocks.viewOtherProfile.profilePage.account,
|
||||
name: 'user',
|
||||
country: 'EN',
|
||||
bio: 'bio',
|
||||
courseCertificates: ['course certificates'],
|
||||
levelOfEducation: 'some level',
|
||||
languageProficiencies: ['some lang'],
|
||||
socialLinks: ['twitter'],
|
||||
timeZone: 'time zone',
|
||||
accountPrivacy: 'all_users',
|
||||
},
|
||||
},
|
||||
})}
|
||||
match={{ params: { username: 'verified' } }} // Override default match
|
||||
/>
|
||||
);
|
||||
const tree = renderer.create(component).toJSON();
|
||||
|
||||
219
src/profile/ProfilePluginPage.jsx
Normal file
219
src/profile/ProfilePluginPage.jsx
Normal file
@@ -0,0 +1,219 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { ensureConfig } from '@edx/frontend-platform';
|
||||
import { AppContext } from '@edx/frontend-platform/react';
|
||||
import { injectIntl, intlShape, FormattedDate } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { faTwitter, faFacebook, faLinkedin } from '@fortawesome/free-brands-svg-icons';
|
||||
import {
|
||||
ActionRow, Avatar, Card, Hyperlink, Icon,
|
||||
} from '@edx/paragon';
|
||||
import { HistoryEdu, VerifiedUser } from '@edx/paragon/icons';
|
||||
|
||||
import get from 'lodash.get';
|
||||
|
||||
import PluginCountry from './forms/PluginCountry';
|
||||
import { Plugin } from '../../plugins';
|
||||
|
||||
// Actions
|
||||
import {
|
||||
fetchProfile,
|
||||
} from './data/actions';
|
||||
|
||||
// Components
|
||||
import PageLoading from './PageLoading';
|
||||
|
||||
// Selectors
|
||||
import { profilePageSelector } from './data/selectors';
|
||||
|
||||
// i18n
|
||||
import messages from './ProfilePage.messages';
|
||||
import eduMessages from './forms/Education.messages';
|
||||
|
||||
import withParams from '../utils/hoc';
|
||||
|
||||
ensureConfig(['CREDENTIALS_BASE_URL', 'LMS_BASE_URL'], 'ProfilePage');
|
||||
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function Fallback() {
|
||||
return (
|
||||
<div>this is broken as all get</div>
|
||||
);
|
||||
}
|
||||
|
||||
const platformDisplayInfo = {
|
||||
facebook: {
|
||||
icon: faFacebook,
|
||||
name: '',
|
||||
},
|
||||
twitter: {
|
||||
icon: faTwitter,
|
||||
name: '',
|
||||
},
|
||||
linkedin: {
|
||||
icon: faLinkedin,
|
||||
name: '',
|
||||
},
|
||||
};
|
||||
|
||||
class ProfilePluginPage extends React.Component {
|
||||
componentDidMount() {
|
||||
this.props.fetchProfile(this.props.params.username);
|
||||
}
|
||||
|
||||
renderContent() {
|
||||
const {
|
||||
profileImage,
|
||||
country,
|
||||
levelOfEducation,
|
||||
socialLinks,
|
||||
isLoadingProfile,
|
||||
dateJoined,
|
||||
name,
|
||||
intl,
|
||||
} = this.props;
|
||||
|
||||
if (isLoadingProfile) {
|
||||
return <PageLoading srMessage={this.props.intl.formatMessage(messages['profile.loading'])} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Plugin fallbackComponent={<Fallback />}>
|
||||
<Card className="mb-2">
|
||||
<Card.Header
|
||||
className="pb-5"
|
||||
subtitle={(
|
||||
<Hyperlink destination={`/u/${this.props.params.username}`} target="_parent">
|
||||
View public profile
|
||||
</Hyperlink>
|
||||
)}
|
||||
actions={
|
||||
(
|
||||
<ActionRow className="mt-3">
|
||||
{socialLinks
|
||||
.filter(({ socialLink }) => Boolean(socialLink))
|
||||
.map(({ platform, socialLink }) => (
|
||||
<StaticListItem
|
||||
key={platform}
|
||||
name={platformDisplayInfo[platform].name}
|
||||
url={socialLink}
|
||||
platform={platform}
|
||||
/>
|
||||
))}
|
||||
</ActionRow>
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Card.Section className="text-center" muted>
|
||||
<Avatar
|
||||
size="xl"
|
||||
className="profile-plugin-avatar"
|
||||
src={profileImage.src}
|
||||
alt="Profile image"
|
||||
/>
|
||||
<p className="h2 mb-0 font-weight-bold">{name}</p>
|
||||
<p className="h3 mb-0 font-weight-bold">{this.props.params.username}</p>
|
||||
<PluginCountry
|
||||
country={country}
|
||||
/>
|
||||
</Card.Section>
|
||||
<Card.Footer className="p-0">
|
||||
<Card.Section className="pgn-icons-cell-vertical">
|
||||
<Icon src={VerifiedUser} />
|
||||
<p>
|
||||
since <FormattedDate value={new Date(dateJoined)} year="numeric" />
|
||||
</p>
|
||||
</Card.Section>
|
||||
<Card.Section className="pgn-icons-cell-vertical">
|
||||
<Icon src={HistoryEdu} />
|
||||
<p>
|
||||
{intl.formatMessage(get(
|
||||
eduMessages,
|
||||
`profile.education.levels.${levelOfEducation}`,
|
||||
eduMessages['profile.education.levels.o'],
|
||||
))}
|
||||
</p>
|
||||
</Card.Section>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
</Plugin>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="profile-page overflow-hidden">
|
||||
{this.renderContent()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const SocialLink = ({ url, name, platform }) => (
|
||||
<a href={url} className="font-weight-bold" target="_parent">
|
||||
<FontAwesomeIcon className="mr-2" icon={platformDisplayInfo[platform].icon} />
|
||||
{name}
|
||||
</a>
|
||||
);
|
||||
|
||||
const StaticListItem = ({ url, name, platform }) => (
|
||||
<ul className="list-inline">
|
||||
<SocialLink name={name} url={url} platform={platform} />
|
||||
</ul>
|
||||
);
|
||||
|
||||
ProfilePluginPage.contextType = AppContext;
|
||||
|
||||
ProfilePluginPage.propTypes = {
|
||||
// Account data
|
||||
dateJoined: PropTypes.string,
|
||||
|
||||
// Country form data
|
||||
country: PropTypes.string,
|
||||
|
||||
// Education form data
|
||||
levelOfEducation: PropTypes.string,
|
||||
|
||||
// Social links form data
|
||||
socialLinks: PropTypes.arrayOf(PropTypes.shape({
|
||||
platform: PropTypes.string,
|
||||
socialLink: PropTypes.string,
|
||||
})),
|
||||
|
||||
// Other data we need
|
||||
profileImage: PropTypes.shape({
|
||||
src: PropTypes.string,
|
||||
isDefault: PropTypes.bool,
|
||||
}),
|
||||
isLoadingProfile: PropTypes.bool.isRequired,
|
||||
|
||||
// Actions
|
||||
fetchProfile: PropTypes.func.isRequired,
|
||||
|
||||
// Router
|
||||
params: PropTypes.shape({
|
||||
username: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
|
||||
// i18n
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
ProfilePluginPage.defaultProps = {
|
||||
profileImage: {},
|
||||
levelOfEducation: null,
|
||||
country: null,
|
||||
socialLinks: [],
|
||||
dateJoined: null,
|
||||
};
|
||||
|
||||
export default connect(
|
||||
profilePageSelector,
|
||||
{
|
||||
fetchProfile,
|
||||
},
|
||||
)(injectIntl(withParams(ProfilePluginPage)));
|
||||
@@ -103,8 +103,11 @@ exports[`<ProfilePage /> Renders correctly in various states test country edit w
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
PluginPOC
|
||||
</div>
|
||||
<div
|
||||
className="col pl-0"
|
||||
className="col"
|
||||
>
|
||||
<div
|
||||
className="d-md-none"
|
||||
@@ -113,7 +116,7 @@ exports[`<ProfilePage /> Renders correctly in various states test country edit w
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
<h1
|
||||
className="h2 mb-0 font-weight-bold"
|
||||
className="h2 mb-0 font-weight-bold text-truncate"
|
||||
>
|
||||
staff
|
||||
</h1>
|
||||
@@ -191,7 +194,7 @@ exports[`<ProfilePage /> Renders correctly in various states test country edit w
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
<h1
|
||||
className="h2 mb-0 font-weight-bold"
|
||||
className="h2 mb-0 font-weight-bold text-truncate"
|
||||
>
|
||||
staff
|
||||
</h1>
|
||||
@@ -1696,7 +1699,7 @@ exports[`<ProfilePage /> Renders correctly in various states test country edit w
|
||||
</svg>
|
||||
</span>
|
||||
<select
|
||||
className="d-inline-block w-auto form-control"
|
||||
className="d-inline-block form-control"
|
||||
id="visibilityCountry"
|
||||
name="visibilityCountry"
|
||||
onChange={[Function]}
|
||||
@@ -2486,8 +2489,11 @@ exports[`<ProfilePage /> Renders correctly in various states test education edit
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
PluginPOC
|
||||
</div>
|
||||
<div
|
||||
className="col pl-0"
|
||||
className="col"
|
||||
>
|
||||
<div
|
||||
className="d-md-none"
|
||||
@@ -2496,7 +2502,7 @@ exports[`<ProfilePage /> Renders correctly in various states test education edit
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
<h1
|
||||
className="h2 mb-0 font-weight-bold"
|
||||
className="h2 mb-0 font-weight-bold text-truncate"
|
||||
>
|
||||
staff
|
||||
</h1>
|
||||
@@ -2574,7 +2580,7 @@ exports[`<ProfilePage /> Renders correctly in various states test education edit
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
<h1
|
||||
className="h2 mb-0 font-weight-bold"
|
||||
className="h2 mb-0 font-weight-bold text-truncate"
|
||||
>
|
||||
staff
|
||||
</h1>
|
||||
@@ -3053,7 +3059,7 @@ exports[`<ProfilePage /> Renders correctly in various states test education edit
|
||||
</svg>
|
||||
</span>
|
||||
<select
|
||||
className="d-inline-block w-auto form-control"
|
||||
className="d-inline-block form-control"
|
||||
id="visibilityLevelOfEducation"
|
||||
name="visibilityLevelOfEducation"
|
||||
onChange={[Function]}
|
||||
@@ -3663,8 +3669,11 @@ exports[`<ProfilePage /> Renders correctly in various states test preferreded la
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
PluginPOC
|
||||
</div>
|
||||
<div
|
||||
className="col pl-0"
|
||||
className="col"
|
||||
>
|
||||
<div
|
||||
className="d-md-none"
|
||||
@@ -3673,7 +3682,7 @@ exports[`<ProfilePage /> Renders correctly in various states test preferreded la
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
<h1
|
||||
className="h2 mb-0 font-weight-bold"
|
||||
className="h2 mb-0 font-weight-bold text-truncate"
|
||||
>
|
||||
staff
|
||||
</h1>
|
||||
@@ -3751,7 +3760,7 @@ exports[`<ProfilePage /> Renders correctly in various states test preferreded la
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
<h1
|
||||
className="h2 mb-0 font-weight-bold"
|
||||
className="h2 mb-0 font-weight-bold text-truncate"
|
||||
>
|
||||
staff
|
||||
</h1>
|
||||
@@ -5015,7 +5024,7 @@ exports[`<ProfilePage /> Renders correctly in various states test preferreded la
|
||||
</svg>
|
||||
</span>
|
||||
<select
|
||||
className="d-inline-block w-auto form-control"
|
||||
className="d-inline-block form-control"
|
||||
id="visibilityLanguageProficiencies"
|
||||
name="visibilityLanguageProficiencies"
|
||||
onChange={[Function]}
|
||||
@@ -5643,7 +5652,7 @@ exports[`<ProfilePage /> Renders correctly in various states test preferreded la
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`<ProfilePage /> Renders correctly in various states viewing other profile 1`] = `
|
||||
exports[`<ProfilePage /> Renders correctly in various states viewing other profile with all fields 1`] = `
|
||||
<div
|
||||
className="profile-page"
|
||||
>
|
||||
@@ -5692,8 +5701,11 @@ exports[`<ProfilePage /> Renders correctly in various states viewing other profi
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
PluginPOC
|
||||
</div>
|
||||
<div
|
||||
className="col pl-0"
|
||||
className="col"
|
||||
>
|
||||
<div
|
||||
className="d-md-none"
|
||||
@@ -5702,9 +5714,9 @@ exports[`<ProfilePage /> Renders correctly in various states viewing other profi
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
<h1
|
||||
className="h2 mb-0 font-weight-bold"
|
||||
className="h2 mb-0 font-weight-bold text-truncate"
|
||||
>
|
||||
verified
|
||||
staff
|
||||
</h1>
|
||||
<p
|
||||
className="mb-0"
|
||||
@@ -5747,7 +5759,52 @@ exports[`<ProfilePage /> Renders correctly in various states viewing other profi
|
||||
</div>
|
||||
<div
|
||||
className="d-none d-md-block float-right"
|
||||
/>
|
||||
>
|
||||
<a
|
||||
className="pgn__hyperlink default-link standalone-link btn btn-primary"
|
||||
href="http://localhost:18150/records"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
View My Records
|
||||
<span
|
||||
className="pgn__hyperlink__external-icon"
|
||||
title="Opens in a new tab"
|
||||
>
|
||||
<span
|
||||
className="pgn__icon"
|
||||
style={
|
||||
Object {
|
||||
"height": "1em",
|
||||
"width": "1em",
|
||||
}
|
||||
}
|
||||
>
|
||||
<svg
|
||||
aria-hidden={true}
|
||||
fill="none"
|
||||
focusable={false}
|
||||
height={24}
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
width={24}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19 19H5V5h7V3H3v18h18v-9h-2v7ZM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
className="sr-only"
|
||||
>
|
||||
in a new tab
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -5763,9 +5820,9 @@ exports[`<ProfilePage /> Renders correctly in various states viewing other profi
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
<h1
|
||||
className="h2 mb-0 font-weight-bold"
|
||||
className="h2 mb-0 font-weight-bold text-truncate"
|
||||
>
|
||||
verified
|
||||
staff
|
||||
</h1>
|
||||
<p
|
||||
className="mb-0"
|
||||
@@ -5808,7 +5865,52 @@ exports[`<ProfilePage /> Renders correctly in various states viewing other profi
|
||||
</div>
|
||||
<div
|
||||
className="d-md-none mb-4"
|
||||
/>
|
||||
>
|
||||
<a
|
||||
className="pgn__hyperlink default-link standalone-link btn btn-primary"
|
||||
href="http://localhost:18150/records"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
View My Records
|
||||
<span
|
||||
className="pgn__hyperlink__external-icon"
|
||||
title="Opens in a new tab"
|
||||
>
|
||||
<span
|
||||
className="pgn__icon"
|
||||
style={
|
||||
Object {
|
||||
"height": "1em",
|
||||
"width": "1em",
|
||||
}
|
||||
}
|
||||
>
|
||||
<svg
|
||||
aria-hidden={true}
|
||||
fill="none"
|
||||
focusable={false}
|
||||
height={24}
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
width={24}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19 19H5V5h7V3H3v18h18v-9h-2v7ZM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
className="sr-only"
|
||||
>
|
||||
in a new tab
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
className="pgn-transition-replace-group position-relative mb-5"
|
||||
style={
|
||||
@@ -5816,7 +5918,32 @@ exports[`<ProfilePage /> Renders correctly in various states viewing other profi
|
||||
"height": null,
|
||||
}
|
||||
}
|
||||
/>
|
||||
>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"padding": ".1px 0",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="editable-item-header mb-2"
|
||||
>
|
||||
<h2
|
||||
className="edit-section-header"
|
||||
id={null}
|
||||
>
|
||||
Full Name
|
||||
</h2>
|
||||
</div>
|
||||
<p
|
||||
className="h5"
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
user
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="pgn-transition-replace-group position-relative mb-5"
|
||||
style={
|
||||
@@ -5824,7 +5951,30 @@ exports[`<ProfilePage /> Renders correctly in various states viewing other profi
|
||||
"height": null,
|
||||
}
|
||||
}
|
||||
/>
|
||||
>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"padding": ".1px 0",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="editable-item-header mb-2"
|
||||
>
|
||||
<h2
|
||||
className="edit-section-header"
|
||||
id={null}
|
||||
>
|
||||
Location
|
||||
</h2>
|
||||
</div>
|
||||
<p
|
||||
className="h5"
|
||||
data-hj-suppress={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="pgn-transition-replace-group position-relative mb-5"
|
||||
style={
|
||||
@@ -5832,7 +5982,30 @@ exports[`<ProfilePage /> Renders correctly in various states viewing other profi
|
||||
"height": null,
|
||||
}
|
||||
}
|
||||
/>
|
||||
>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"padding": ".1px 0",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="editable-item-header mb-2"
|
||||
>
|
||||
<h2
|
||||
className="edit-section-header"
|
||||
id={null}
|
||||
>
|
||||
Primary Language Spoken
|
||||
</h2>
|
||||
</div>
|
||||
<p
|
||||
className="h5"
|
||||
data-hj-suppress={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="pgn-transition-replace-group position-relative mb-5"
|
||||
style={
|
||||
@@ -5840,7 +6013,32 @@ exports[`<ProfilePage /> Renders correctly in various states viewing other profi
|
||||
"height": null,
|
||||
}
|
||||
}
|
||||
/>
|
||||
>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"padding": ".1px 0",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="editable-item-header mb-2"
|
||||
>
|
||||
<h2
|
||||
className="edit-section-header"
|
||||
id={null}
|
||||
>
|
||||
Education
|
||||
</h2>
|
||||
</div>
|
||||
<p
|
||||
className="h5"
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
Other education
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="pgn-transition-replace-group position-relative mb-5"
|
||||
style={
|
||||
@@ -5848,7 +6046,29 @@ exports[`<ProfilePage /> Renders correctly in various states viewing other profi
|
||||
"height": null,
|
||||
}
|
||||
}
|
||||
/>
|
||||
>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"padding": ".1px 0",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="editable-item-header mb-2"
|
||||
>
|
||||
<h2
|
||||
className="edit-section-header"
|
||||
id={null}
|
||||
>
|
||||
Social Links
|
||||
</h2>
|
||||
</div>
|
||||
<ul
|
||||
className="list-unstyled"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="pt-md-3 col-md-8 col-lg-7 offset-lg-1"
|
||||
@@ -5860,7 +6080,32 @@ exports[`<ProfilePage /> Renders correctly in various states viewing other profi
|
||||
"height": null,
|
||||
}
|
||||
}
|
||||
/>
|
||||
>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"padding": ".1px 0",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="editable-item-header mb-2"
|
||||
>
|
||||
<h2
|
||||
className="edit-section-header"
|
||||
id={null}
|
||||
>
|
||||
About Me
|
||||
</h2>
|
||||
</div>
|
||||
<p
|
||||
className="lead"
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
bio
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="pgn-transition-replace-group position-relative mb-4"
|
||||
style={
|
||||
@@ -5868,7 +6113,27 @@ exports[`<ProfilePage /> Renders correctly in various states viewing other profi
|
||||
"height": null,
|
||||
}
|
||||
}
|
||||
/>
|
||||
>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"padding": ".1px 0",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="editable-item-header mb-2"
|
||||
>
|
||||
<h2
|
||||
className="edit-section-header"
|
||||
id={null}
|
||||
>
|
||||
My Certificates
|
||||
</h2>
|
||||
</div>
|
||||
You don't have any certificates yet.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -5947,8 +6212,11 @@ exports[`<ProfilePage /> Renders correctly in various states viewing own profile
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
PluginPOC
|
||||
</div>
|
||||
<div
|
||||
className="col pl-0"
|
||||
className="col"
|
||||
>
|
||||
<div
|
||||
className="d-md-none"
|
||||
@@ -5957,7 +6225,7 @@ exports[`<ProfilePage /> Renders correctly in various states viewing own profile
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
<h1
|
||||
className="h2 mb-0 font-weight-bold"
|
||||
className="h2 mb-0 font-weight-bold text-truncate"
|
||||
>
|
||||
staff
|
||||
</h1>
|
||||
@@ -6035,7 +6303,7 @@ exports[`<ProfilePage /> Renders correctly in various states viewing own profile
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
<h1
|
||||
className="h2 mb-0 font-weight-bold"
|
||||
className="h2 mb-0 font-weight-bold text-truncate"
|
||||
>
|
||||
staff
|
||||
</h1>
|
||||
@@ -6997,8 +7265,11 @@ exports[`<ProfilePage /> Renders correctly in various states while saving an edi
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
PluginPOC
|
||||
</div>
|
||||
<div
|
||||
className="col pl-0"
|
||||
className="col"
|
||||
>
|
||||
<div
|
||||
className="d-md-none"
|
||||
@@ -7007,7 +7278,7 @@ exports[`<ProfilePage /> Renders correctly in various states while saving an edi
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
<h1
|
||||
className="h2 mb-0 font-weight-bold"
|
||||
className="h2 mb-0 font-weight-bold text-truncate"
|
||||
>
|
||||
staff
|
||||
</h1>
|
||||
@@ -7085,7 +7356,7 @@ exports[`<ProfilePage /> Renders correctly in various states while saving an edi
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
<h1
|
||||
className="h2 mb-0 font-weight-bold"
|
||||
className="h2 mb-0 font-weight-bold text-truncate"
|
||||
>
|
||||
staff
|
||||
</h1>
|
||||
@@ -7773,7 +8044,7 @@ exports[`<ProfilePage /> Renders correctly in various states while saving an edi
|
||||
</svg>
|
||||
</span>
|
||||
<select
|
||||
className="d-inline-block w-auto form-control"
|
||||
className="d-inline-block form-control"
|
||||
id="visibilityBio"
|
||||
name="visibilityBio"
|
||||
onChange={[Function]}
|
||||
@@ -8114,8 +8385,11 @@ exports[`<ProfilePage /> Renders correctly in various states while saving an edi
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
PluginPOC
|
||||
</div>
|
||||
<div
|
||||
className="col pl-0"
|
||||
className="col"
|
||||
>
|
||||
<div
|
||||
className="d-md-none"
|
||||
@@ -8124,7 +8398,7 @@ exports[`<ProfilePage /> Renders correctly in various states while saving an edi
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
<h1
|
||||
className="h2 mb-0 font-weight-bold"
|
||||
className="h2 mb-0 font-weight-bold text-truncate"
|
||||
>
|
||||
staff
|
||||
</h1>
|
||||
@@ -8202,7 +8476,7 @@ exports[`<ProfilePage /> Renders correctly in various states while saving an edi
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
<h1
|
||||
className="h2 mb-0 font-weight-bold"
|
||||
className="h2 mb-0 font-weight-bold text-truncate"
|
||||
>
|
||||
staff
|
||||
</h1>
|
||||
@@ -8898,7 +9172,7 @@ exports[`<ProfilePage /> Renders correctly in various states while saving an edi
|
||||
</svg>
|
||||
</span>
|
||||
<select
|
||||
className="d-inline-block w-auto form-control"
|
||||
className="d-inline-block form-control"
|
||||
id="visibilityBio"
|
||||
name="visibilityBio"
|
||||
onChange={[Function]}
|
||||
@@ -9239,8 +9513,11 @@ exports[`<ProfilePage /> Renders correctly in various states without credentials
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
PluginPOC
|
||||
</div>
|
||||
<div
|
||||
className="col pl-0"
|
||||
className="col"
|
||||
>
|
||||
<div
|
||||
className="d-md-none"
|
||||
@@ -9249,7 +9526,7 @@ exports[`<ProfilePage /> Renders correctly in various states without credentials
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
<h1
|
||||
className="h2 mb-0 font-weight-bold"
|
||||
className="h2 mb-0 font-weight-bold text-truncate"
|
||||
>
|
||||
staff
|
||||
</h1>
|
||||
@@ -9282,7 +9559,7 @@ exports[`<ProfilePage /> Renders correctly in various states without credentials
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
<h1
|
||||
className="h2 mb-0 font-weight-bold"
|
||||
className="h2 mb-0 font-weight-bold text-truncate"
|
||||
>
|
||||
staff
|
||||
</h1>
|
||||
|
||||
@@ -66,6 +66,25 @@ export function* handleFetchProfile(action) {
|
||||
} else {
|
||||
[account, courseCertificates] = result;
|
||||
}
|
||||
|
||||
// Set initial visibility values for account
|
||||
// Set account_privacy as custom is necessary so that when viewing another user's profile,
|
||||
// their full name is displayed and change visibility forms are worked correctly
|
||||
if (isAuthenticatedUserProfile && result[0].accountPrivacy === 'all_users') {
|
||||
yield call(ProfileApiService.patchPreferences, action.payload.username, {
|
||||
account_privacy: 'custom',
|
||||
'visibility.name': 'all_users',
|
||||
'visibility.bio': 'all_users',
|
||||
'visibility.course_certificates': 'all_users',
|
||||
'visibility.country': 'all_users',
|
||||
'visibility.date_joined': 'all_users',
|
||||
'visibility.level_of_education': 'all_users',
|
||||
'visibility.language_proficiencies': 'all_users',
|
||||
'visibility.social_links': 'all_users',
|
||||
'visibility.time_zone': 'all_users',
|
||||
});
|
||||
}
|
||||
|
||||
yield put(fetchProfileSuccess(
|
||||
account,
|
||||
preferences,
|
||||
|
||||
@@ -35,9 +35,12 @@ export const editableFormModeSelector = createSelector(
|
||||
// or is being hidden from us (for other users' profiles)
|
||||
let propExists = account[formId] != null && account[formId].length > 0;
|
||||
propExists = formId === 'certificates' ? certificates.length > 0 : propExists; // overwrite for certificates
|
||||
// If this isn't the current user's profile or if
|
||||
// If this isn't the current user's profile
|
||||
if (!isAuthenticatedUserProfile) {
|
||||
return 'static';
|
||||
}
|
||||
// the current user has no age set / under 13 ...
|
||||
if (!isAuthenticatedUserProfile || account.requiresParentalConsent) {
|
||||
if (account.requiresParentalConsent) {
|
||||
// then there are only two options: static or nothing.
|
||||
// We use 'null' as a return value because the consumers of
|
||||
// getMode render nothing at all on a mode of null.
|
||||
@@ -228,13 +231,13 @@ export const visibilitiesSelector = createSelector(
|
||||
switch (accountPrivacy) {
|
||||
case 'custom':
|
||||
return {
|
||||
visibilityBio: preferences.visibilityBio || 'private',
|
||||
visibilityCourseCertificates: preferences.visibilityCourseCertificates || 'private',
|
||||
visibilityCountry: preferences.visibilityCountry || 'private',
|
||||
visibilityLevelOfEducation: preferences.visibilityLevelOfEducation || 'private',
|
||||
visibilityLanguageProficiencies: preferences.visibilityLanguageProficiencies || 'private',
|
||||
visibilityName: preferences.visibilityName || 'private',
|
||||
visibilitySocialLinks: preferences.visibilitySocialLinks || 'private',
|
||||
visibilityBio: preferences.visibilityBio || 'all_users',
|
||||
visibilityCourseCertificates: preferences.visibilityCourseCertificates || 'all_users',
|
||||
visibilityCountry: preferences.visibilityCountry || 'all_users',
|
||||
visibilityLevelOfEducation: preferences.visibilityLevelOfEducation || 'all_users',
|
||||
visibilityLanguageProficiencies: preferences.visibilityLanguageProficiencies || 'all_users',
|
||||
visibilityName: preferences.visibilityName || 'all_users',
|
||||
visibilitySocialLinks: preferences.visibilitySocialLinks || 'all_users',
|
||||
};
|
||||
case 'private':
|
||||
return {
|
||||
|
||||
40
src/profile/forms/PluginCountry.jsx
Normal file
40
src/profile/forms/PluginCountry.jsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { injectIntl } from '@edx/frontend-platform/i18n';
|
||||
import { Icon } from '@edx/paragon';
|
||||
import { LocationOn } from '@edx/paragon/icons';
|
||||
|
||||
// Selectors
|
||||
import { countrySelector } from '../data/selectors';
|
||||
|
||||
// eslint-disable-next-line react/prefer-stateless-function
|
||||
class PluginCountry extends React.Component {
|
||||
render() {
|
||||
const {
|
||||
country,
|
||||
countryMessages,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div className="pgn-icons-cell-horizontal">
|
||||
<Icon src={LocationOn} />
|
||||
<p className="h5 mt-1 ml-1">{countryMessages[country]}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
PluginCountry.propTypes = {
|
||||
country: PropTypes.string,
|
||||
countryMessages: PropTypes.objectOf(PropTypes.string).isRequired,
|
||||
};
|
||||
|
||||
PluginCountry.defaultProps = {
|
||||
country: null,
|
||||
};
|
||||
|
||||
export default connect(
|
||||
countrySelector,
|
||||
{},
|
||||
)(injectIntl(PluginCountry));
|
||||
@@ -119,7 +119,7 @@ exports[`<SocialLinks /> calls social links with edit mode bio 1`] = `
|
||||
</svg>
|
||||
</span>
|
||||
<select
|
||||
className="d-inline-block w-auto form-control"
|
||||
className="d-inline-block form-control"
|
||||
id="visibilitySocialLinks"
|
||||
name="visibilitySocialLinks"
|
||||
onChange={[Function]}
|
||||
|
||||
@@ -39,7 +39,7 @@ const VisibilitySelect = ({ intl, className, ...props }) => {
|
||||
<span className="d-inline-block ml-1 mr-2" style={{ width: '1.5rem' }}>
|
||||
<FontAwesomeIcon icon={icon} />
|
||||
</span>
|
||||
<select className="d-inline-block w-auto form-control" {...props}>
|
||||
<select className="d-inline-block form-control" {...props}>
|
||||
<option key="private" value="private">
|
||||
{intl.formatMessage(messages['profile.visibility.who.just.me'])}
|
||||
</option>
|
||||
|
||||
@@ -3,3 +3,4 @@ export { default as saga } from './data/sagas';
|
||||
export { default as ProfilePage } from './ProfilePage';
|
||||
export { default as NotFoundPage } from './NotFoundPage';
|
||||
export { default as messages } from './ProfilePage.messages';
|
||||
export { default as ProfilePluginPage } from './ProfilePluginPage';
|
||||
|
||||
@@ -162,4 +162,28 @@
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.pgn-icons-cell-vertical {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
margin: 1px;
|
||||
}
|
||||
.pgn-icons-cell-horizontal {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
.profile-plugin-avatar {
|
||||
@include media-breakpoint-up(xs) {
|
||||
max-width: 12rem;
|
||||
margin-right: 0;
|
||||
margin-top: -4rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@ import {
|
||||
PageWrap,
|
||||
} from '@edx/frontend-platform/react';
|
||||
import { Routes, Route } from 'react-router-dom';
|
||||
import { ProfilePage, NotFoundPage } from '../profile';
|
||||
import { ProfilePage, NotFoundPage, ProfilePluginPage } from '../profile';
|
||||
|
||||
const AppRoutes = () => (
|
||||
<Routes>
|
||||
<Route path="/u/:username" element={<AuthenticatedPageRoute><ProfilePage /></AuthenticatedPageRoute>} />
|
||||
<Route path="/u/:username/plugin" element={<AuthenticatedPageRoute><ProfilePluginPage /></AuthenticatedPageRoute>} />
|
||||
<Route path="/notfound" element={<PageWrap><NotFoundPage /></PageWrap>} />
|
||||
<Route path="*" element={<PageWrap><NotFoundPage /></PageWrap>} />
|
||||
</Routes>
|
||||
|
||||
@@ -15,6 +15,7 @@ jest.mock('@edx/frontend-platform/auth', () => ({
|
||||
jest.mock('../profile', () => ({
|
||||
ProfilePage: () => (<div>Profile page</div>),
|
||||
NotFoundPage: () => (<div>Not found page</div>),
|
||||
ProfilePluginPage: () => (<div>Plugin page</div>),
|
||||
}));
|
||||
|
||||
const RoutesWithProvider = (context, path) => (
|
||||
@@ -54,6 +55,22 @@ describe('routes', () => {
|
||||
expect(screen.getByText('Profile page')).toBeTruthy();
|
||||
});
|
||||
|
||||
test('Profile Plugin page should be accessible for authenticated users', () => {
|
||||
render(
|
||||
RoutesWithProvider(
|
||||
{
|
||||
authenticatedUser: {
|
||||
username: 'edx',
|
||||
email: 'edx@example.com',
|
||||
},
|
||||
config: getConfig(),
|
||||
},
|
||||
'/u/edx/plugin',
|
||||
),
|
||||
);
|
||||
expect(screen.getByText('Plugin page')).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should show NotFound page for a bad route', () => {
|
||||
render(
|
||||
RoutesWithProvider(unauthenticatedUser, '/nonMatchingRoute'),
|
||||
|
||||
Reference in New Issue
Block a user