Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
650e9321b1 | ||
|
|
e8a8cca483 | ||
|
|
f5d2a34660 | ||
|
|
97d3a29a7f | ||
|
|
5b8f67e8d2 | ||
|
|
c6e33307ba | ||
|
|
a4df8f7238 | ||
|
|
15b76edb5d |
1
.env
1
.env
@@ -30,4 +30,3 @@ ENTERPRISE_MARKETING_URL=''
|
||||
ENTERPRISE_MARKETING_UTM_SOURCE=''
|
||||
ENTERPRISE_MARKETING_UTM_CAMPAIGN=''
|
||||
ENTERPRISE_MARKETING_FOOTER_UTM_MEDIUM=''
|
||||
BULK_MANAGEMENT_SPECIAL_ACCESS_COURSE_IDS=''
|
||||
|
||||
@@ -36,4 +36,3 @@ ENTERPRISE_MARKETING_URL='http://example.com'
|
||||
ENTERPRISE_MARKETING_UTM_SOURCE='example.com'
|
||||
ENTERPRISE_MARKETING_UTM_CAMPAIGN='example.com Referral'
|
||||
ENTERPRISE_MARKETING_FOOTER_UTM_MEDIUM='Footer'
|
||||
BULK_MANAGEMENT_SPECIAL_ACCESS_COURSE_IDS=''
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
const { createConfig } = require('@edx/frontend-build');
|
||||
|
||||
const config = createConfig('eslint');
|
||||
const config = createConfig('eslint', {
|
||||
rules: {
|
||||
'import/no-named-as-default': 'off',
|
||||
'import/no-named-as-default-member': 'off',
|
||||
'import/no-self-import': 'off',
|
||||
'spaced-comment': ['error', 'always', { 'block': { 'exceptions': ['*'] } }],
|
||||
},
|
||||
});
|
||||
|
||||
config.settings = {
|
||||
"import/resolver": {
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -17,3 +17,7 @@ dist/
|
||||
### Development environments ###
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
### transifex ###
|
||||
src/i18n/transifex_input.json
|
||||
temp
|
||||
|
||||
8
.tx/config
Normal file
8
.tx/config
Normal file
@@ -0,0 +1,8 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
|
||||
[edx-platform.frontend-app-gradebook]
|
||||
file_filter = src/i18n/messages/<lang>.json
|
||||
source_file = src/i18n/transifex_input.json
|
||||
source_lang = en
|
||||
type = KEYVALUEJSON
|
||||
64
Makefile
64
Makefile
@@ -2,8 +2,64 @@ npm-install-%: ## install specified % npm package
|
||||
npm install $* --save-dev
|
||||
git add package.json
|
||||
|
||||
validate-no-uncommitted-package-lock-changes:
|
||||
git diff --exit-code package-lock.json
|
||||
transifex_resource = frontend-app-gradebook
|
||||
transifex_langs = "ar,fr,es_419,zh_CN"
|
||||
|
||||
test:
|
||||
npm run test
|
||||
transifex_utils = ./node_modules/.bin/transifex-utils.js
|
||||
i18n = ./src/i18n
|
||||
transifex_input = $(i18n)/transifex_input.json
|
||||
tx_url1 = https://www.transifex.com/api/2/project/edx-platform/resource/$(transifex_resource)/translation/en/strings/
|
||||
tx_url2 = https://www.transifex.com/api/2/project/edx-platform/resource/$(transifex_resource)/source/
|
||||
|
||||
# This directory must match .babelrc .
|
||||
transifex_temp = ./temp/babel-plugin-react-intl
|
||||
|
||||
NPM_TESTS=build i18n_extract lint test is-es5
|
||||
|
||||
.PHONY: test
|
||||
test: $(addprefix test.npm.,$(NPM_TESTS)) ## validate ci suite
|
||||
|
||||
.PHONY: test.npm.*
|
||||
test.npm.%: validate-no-uncommitted-package-lock-changes
|
||||
test -d node_modules || $(MAKE) requirements
|
||||
npm run $(*)
|
||||
|
||||
.PHONY: requirements
|
||||
requirements: ## install ci requirements
|
||||
npm ci
|
||||
|
||||
i18n.extract:
|
||||
# Pulling display strings from .jsx files into .json files...
|
||||
rm -rf $(transifex_temp)
|
||||
npm run-script i18n_extract
|
||||
|
||||
i18n.concat:
|
||||
# Gathering JSON messages into one file...
|
||||
$(transifex_utils) $(transifex_temp) $(transifex_input)
|
||||
|
||||
extract_translations: | requirements i18n.extract i18n.concat
|
||||
|
||||
# Despite the name, we actually need this target to detect changes in the incoming translated message files as well.
|
||||
detect_changed_source_translations:
|
||||
# Checking for changed translations...
|
||||
git diff --exit-code $(i18n)
|
||||
|
||||
# Pushes translations to Transifex. You must run make extract_translations first.
|
||||
push_translations:
|
||||
# Pushing strings to Transifex...
|
||||
tx push -s
|
||||
# Fetching hashes from Transifex...
|
||||
./node_modules/reactifex/bash_scripts/get_hashed_strings.sh $(tx_url1)
|
||||
# Writing out comments to file...
|
||||
$(transifex_utils) $(transifex_temp) --comments
|
||||
# Pushing comments to Transifex...
|
||||
./node_modules/reactifex/bash_scripts/put_comments.sh $(tx_url2)
|
||||
|
||||
# Pulls translations from Transifex.
|
||||
pull_translations:
|
||||
tx pull -f --mode reviewed --language=$(transifex_langs)
|
||||
|
||||
# This target is used by Travis.
|
||||
validate-no-uncommitted-package-lock-changes:
|
||||
# Checking for package-lock.json changes...
|
||||
git diff --exit-code package-lock.json
|
||||
|
||||
@@ -68,7 +68,7 @@ Confirm the following workflows:
|
||||
- [ ] Clicking "Save Grade" applies the override, shows the successful "grade has been edited" banner and updates score in grades table (may take a few seconds).
|
||||
- [ ] Opening back up the "Edit Grades" modal shows the change as an entry in the override history table.
|
||||
|
||||
- [ ] *Masters only*: "Bulk Management" allows overriding grades in bulk.
|
||||
- [ ] *Master's (or selectively-enabled) only*: "Bulk Management" allows overriding grades in bulk.
|
||||
- Open a non-masters-track course.
|
||||
- [ ] Verify that the "Bulk Management" tab does not appear.
|
||||
- [ ] Verify that the "Bulk Management" button does not appear.
|
||||
|
||||
@@ -14,7 +14,7 @@ Suggested resources:
|
||||
- [Adding Exercises and Tools](https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/grading/index.html)
|
||||
- [Set the Assignment Type and Due Date for a Subsection](https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/developing_course/course_subsections.html#set-the-assignment-type-and-due-date-for-a-subsection)
|
||||
|
||||
## Enable Gradebook and feature toggles for course
|
||||
## Enable Gradebook for course
|
||||
|
||||
See README.md #Quickstart for more detailed instructions.
|
||||
|
||||
@@ -25,7 +25,13 @@ As an admin user, visit Django Admin (`{lms-url}/admin`) to modify features.
|
||||
- [ ] Set name to `grades.assume_zero_grade_if_absent`, select "Active", and click "Save"
|
||||
- In Waffle_Utils > Waffle flag course overrides:
|
||||
- [ ] Add a new flag called `grades.writeable_gradebook`, select "Force On", and enable it for your course
|
||||
- [ ] Add a new flag called `grades.bulk_management`, select "Force On", and enable it for your course
|
||||
|
||||
## Enable Bulk Management
|
||||
|
||||
Bulk Management is an added feature to allow modifying grades in bulk via CSV upload. Bulk Management is default enabled for Master's track courses but can be selectively enabled for other courses with a waffle flag following the steps below.
|
||||
|
||||
- In Waffle_Utils > Waffle flag course overrides:
|
||||
- [ ] Add a new flag called `grades.bulk_management`, select "Force On", and enable it for your course.
|
||||
|
||||
## Create a Master's track for testing Master's-only features
|
||||
|
||||
|
||||
@@ -8,4 +8,8 @@ module.exports = createConfig('jest', {
|
||||
snapshotSerializers: [
|
||||
'enzyme-to-json/serializer',
|
||||
],
|
||||
coveragePathIgnorePatterns: [
|
||||
'src/segment.js',
|
||||
'src/postcss.config.js',
|
||||
],
|
||||
});
|
||||
|
||||
874
package-lock.json
generated
874
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@edx/frontend-app-gradebook",
|
||||
"version": "1.4.36",
|
||||
"version": "1.4.46",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -18156,7 +18156,7 @@
|
||||
"dependencies": {
|
||||
"JSONStream": {
|
||||
"version": "1.3.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18166,13 +18166,13 @@
|
||||
},
|
||||
"abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"agent-base": {
|
||||
"version": "4.3.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18181,7 +18181,7 @@
|
||||
},
|
||||
"agentkeepalive": {
|
||||
"version": "3.5.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18190,7 +18190,7 @@
|
||||
},
|
||||
"ajv": {
|
||||
"version": "5.5.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18202,7 +18202,7 @@
|
||||
},
|
||||
"ansi-align": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18211,13 +18211,13 @@
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18226,31 +18226,31 @@
|
||||
},
|
||||
"ansicolors": {
|
||||
"version": "0.3.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=",
|
||||
"dev": true
|
||||
},
|
||||
"ansistyles": {
|
||||
"version": "0.1.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-XeYEFb2gcbs3EnhUyGT0GyMlRTk=",
|
||||
"dev": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"archy": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
|
||||
"dev": true
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.1.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18260,7 +18260,7 @@
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18275,7 +18275,7 @@
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18286,13 +18286,13 @@
|
||||
},
|
||||
"asap": {
|
||||
"version": "2.0.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
|
||||
"dev": true
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18301,37 +18301,37 @@
|
||||
},
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
||||
"dev": true
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
||||
"dev": true
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
|
||||
"dev": true
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.8.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
|
||||
"dev": true
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
@@ -18341,7 +18341,7 @@
|
||||
},
|
||||
"bin-links": {
|
||||
"version": "1.1.8",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-KgmVfx+QqggqP9dA3iIc5pA4T1qEEEL+hOhOhNPaUm77OTrJoOXE/C05SJLNJe6m/2wUK7F1tDSou7n5TfCDzQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18355,13 +18355,13 @@
|
||||
},
|
||||
"bluebird": {
|
||||
"version": "3.5.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==",
|
||||
"dev": true
|
||||
},
|
||||
"boxen": {
|
||||
"version": "1.3.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18376,7 +18376,7 @@
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18386,31 +18386,31 @@
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==",
|
||||
"dev": true
|
||||
},
|
||||
"builtins": {
|
||||
"version": "1.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=",
|
||||
"dev": true
|
||||
},
|
||||
"byline": {
|
||||
"version": "5.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=",
|
||||
"dev": true
|
||||
},
|
||||
"byte-size": {
|
||||
"version": "5.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-/XuKeqWocKsYa/cBY1YbSJSWWqTi4cFgr9S6OyM7PBaPbr9zvNGwWP33vt0uqGhwDdN+y3yhbXVILEUpnwEWGw==",
|
||||
"dev": true
|
||||
},
|
||||
"cacache": {
|
||||
"version": "12.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18433,31 +18433,31 @@
|
||||
},
|
||||
"call-limit": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-5twvci5b9eRBw2wCfPtN0GmlR2/gadZqyFpPhOK6CvMFoFgA+USnZ6Jpu1lhG9h85pQ3Ouil3PfXWRD4EUaRiQ==",
|
||||
"dev": true
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "4.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
|
||||
"dev": true
|
||||
},
|
||||
"capture-stack-trace": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=",
|
||||
"dev": true
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18468,19 +18468,19 @@
|
||||
},
|
||||
"chownr": {
|
||||
"version": "1.1.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
|
||||
"dev": true
|
||||
},
|
||||
"ci-info": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
|
||||
"dev": true
|
||||
},
|
||||
"cidr-regex": {
|
||||
"version": "2.0.10",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-sB3ogMQXWvreNPbJUZMRApxuRYd+KoIo4RGQ81VatjmMW6WJPo+IJZ2846FGItr9VzKo5w7DXzijPLGtSd0N3Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18489,13 +18489,13 @@
|
||||
},
|
||||
"cli-boxes": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=",
|
||||
"dev": true
|
||||
},
|
||||
"cli-columns": {
|
||||
"version": "3.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-ZzLZcpee/CrkRKHwjgj6E5yWoY4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18505,7 +18505,7 @@
|
||||
},
|
||||
"cli-table3": {
|
||||
"version": "0.5.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18516,7 +18516,7 @@
|
||||
},
|
||||
"cliui": {
|
||||
"version": "5.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18527,19 +18527,19 @@
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"dev": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
|
||||
"dev": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "3.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18550,7 +18550,7 @@
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "5.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18561,13 +18561,13 @@
|
||||
},
|
||||
"clone": {
|
||||
"version": "1.0.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
|
||||
"dev": true
|
||||
},
|
||||
"cmd-shim": {
|
||||
"version": "3.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-DtGg+0xiFhQIntSBRzL2fRQBnmtAVwXIDo4Qq46HPpObYquxMaZS4sb82U9nH91qJrlosC1wa9gwr0QyL/HypA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18577,19 +18577,19 @@
|
||||
},
|
||||
"co": {
|
||||
"version": "4.6.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
|
||||
"dev": true
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
||||
"dev": true
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18598,20 +18598,20 @@
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||
"dev": true
|
||||
},
|
||||
"colors": {
|
||||
"version": "1.3.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"columnify": {
|
||||
"version": "1.5.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18621,7 +18621,7 @@
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18630,13 +18630,13 @@
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
},
|
||||
"concat-stream": {
|
||||
"version": "1.6.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18648,7 +18648,7 @@
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18663,7 +18663,7 @@
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18674,7 +18674,7 @@
|
||||
},
|
||||
"config-chain": {
|
||||
"version": "1.1.12",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18684,7 +18684,7 @@
|
||||
},
|
||||
"configstore": {
|
||||
"version": "3.1.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-nlOhI4+fdzoK5xmJ+NY+1gZK56bwEaWZr8fYuXohZ9Vkc1o3a4T/R3M+yE/w7x/ZVJ1zF8c+oaOvF0dztdUgmA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18698,13 +18698,13 @@
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
||||
"dev": true
|
||||
},
|
||||
"copy-concurrently": {
|
||||
"version": "1.0.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18718,13 +18718,13 @@
|
||||
"dependencies": {
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
||||
"dev": true
|
||||
},
|
||||
"iferr": {
|
||||
"version": "0.1.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
|
||||
"dev": true
|
||||
}
|
||||
@@ -18732,13 +18732,13 @@
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"dev": true
|
||||
},
|
||||
"create-error-class": {
|
||||
"version": "3.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18747,7 +18747,7 @@
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "5.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18758,7 +18758,7 @@
|
||||
"dependencies": {
|
||||
"lru-cache": {
|
||||
"version": "4.1.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18768,7 +18768,7 @@
|
||||
},
|
||||
"yallist": {
|
||||
"version": "2.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
|
||||
"dev": true
|
||||
}
|
||||
@@ -18776,19 +18776,19 @@
|
||||
},
|
||||
"crypto-random-string": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
|
||||
"dev": true
|
||||
},
|
||||
"cyclist": {
|
||||
"version": "0.2.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=",
|
||||
"dev": true
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18797,7 +18797,7 @@
|
||||
},
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18806,7 +18806,7 @@
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
"dev": true
|
||||
}
|
||||
@@ -18814,31 +18814,31 @@
|
||||
},
|
||||
"debuglog": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=",
|
||||
"dev": true
|
||||
},
|
||||
"decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
|
||||
"dev": true
|
||||
},
|
||||
"decode-uri-component": {
|
||||
"version": "0.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
|
||||
"dev": true
|
||||
},
|
||||
"deep-extend": {
|
||||
"version": "0.6.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
|
||||
"dev": true
|
||||
},
|
||||
"defaults": {
|
||||
"version": "1.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18847,7 +18847,7 @@
|
||||
},
|
||||
"define-properties": {
|
||||
"version": "1.1.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18856,31 +18856,31 @@
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||
"dev": true
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
||||
"dev": true
|
||||
},
|
||||
"detect-indent": {
|
||||
"version": "5.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=",
|
||||
"dev": true
|
||||
},
|
||||
"detect-newline": {
|
||||
"version": "2.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=",
|
||||
"dev": true
|
||||
},
|
||||
"dezalgo": {
|
||||
"version": "1.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18890,7 +18890,7 @@
|
||||
},
|
||||
"dot-prop": {
|
||||
"version": "4.2.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18899,19 +18899,19 @@
|
||||
},
|
||||
"dotenv": {
|
||||
"version": "5.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow==",
|
||||
"dev": true
|
||||
},
|
||||
"duplexer3": {
|
||||
"version": "0.1.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
|
||||
"dev": true
|
||||
},
|
||||
"duplexify": {
|
||||
"version": "3.6.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18923,7 +18923,7 @@
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18938,7 +18938,7 @@
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18949,7 +18949,7 @@
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
@@ -18960,19 +18960,19 @@
|
||||
},
|
||||
"editor": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-YMf4e9YrzGqJT6jM1q+3gjok90I=",
|
||||
"dev": true
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "7.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
|
||||
"dev": true
|
||||
},
|
||||
"encoding": {
|
||||
"version": "0.1.12",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18981,7 +18981,7 @@
|
||||
},
|
||||
"end-of-stream": {
|
||||
"version": "1.4.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -18990,19 +18990,19 @@
|
||||
},
|
||||
"env-paths": {
|
||||
"version": "2.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==",
|
||||
"dev": true
|
||||
},
|
||||
"err-code": {
|
||||
"version": "1.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=",
|
||||
"dev": true
|
||||
},
|
||||
"errno": {
|
||||
"version": "0.1.7",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19011,7 +19011,7 @@
|
||||
},
|
||||
"es-abstract": {
|
||||
"version": "1.12.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19024,7 +19024,7 @@
|
||||
},
|
||||
"es-to-primitive": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19035,13 +19035,13 @@
|
||||
},
|
||||
"es6-promise": {
|
||||
"version": "4.2.8",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
|
||||
"dev": true
|
||||
},
|
||||
"es6-promisify": {
|
||||
"version": "5.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19050,13 +19050,13 @@
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
||||
"dev": true
|
||||
},
|
||||
"execa": {
|
||||
"version": "0.7.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19071,7 +19071,7 @@
|
||||
"dependencies": {
|
||||
"get-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
|
||||
"dev": true
|
||||
}
|
||||
@@ -19079,43 +19079,43 @@
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
||||
"dev": true
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.3.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "1.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
|
||||
"dev": true
|
||||
},
|
||||
"figgy-pudding": {
|
||||
"version": "3.5.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==",
|
||||
"dev": true
|
||||
},
|
||||
"find-npm-prefix": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-KEftzJ+H90x6pcKtdXZEPsQse8/y/UnvzRKrOSQFprnrGaFuJ62fVkP34Iu2IYuMvyauCyoLTNkJZgrrGA2wkA==",
|
||||
"dev": true
|
||||
},
|
||||
"flush-write-stream": {
|
||||
"version": "1.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19125,7 +19125,7 @@
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19140,7 +19140,7 @@
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19151,13 +19151,13 @@
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
|
||||
"dev": true
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.3.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19168,7 +19168,7 @@
|
||||
},
|
||||
"from2": {
|
||||
"version": "2.3.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19178,7 +19178,7 @@
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19193,7 +19193,7 @@
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19204,7 +19204,7 @@
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "1.2.7",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19213,7 +19213,7 @@
|
||||
"dependencies": {
|
||||
"minipass": {
|
||||
"version": "2.9.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19225,7 +19225,7 @@
|
||||
},
|
||||
"fs-vacuum": {
|
||||
"version": "1.2.10",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-t2Kb7AekAxolSP35n17PHMizHjY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19236,7 +19236,7 @@
|
||||
},
|
||||
"fs-write-stream-atomic": {
|
||||
"version": "1.0.10",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19248,13 +19248,13 @@
|
||||
"dependencies": {
|
||||
"iferr": {
|
||||
"version": "0.1.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
|
||||
"dev": true
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19269,7 +19269,7 @@
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19280,19 +19280,19 @@
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
|
||||
"dev": true
|
||||
},
|
||||
"gauge": {
|
||||
"version": "2.7.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19308,13 +19308,13 @@
|
||||
"dependencies": {
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
||||
"dev": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19327,13 +19327,13 @@
|
||||
},
|
||||
"genfun": {
|
||||
"version": "5.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==",
|
||||
"dev": true
|
||||
},
|
||||
"gentle-fs": {
|
||||
"version": "2.3.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-OlwBBwqCFPcjm33rF2BjW+Pr6/ll2741l+xooiwTCeaX2CA1ZuclavyMBe0/KlR21/XGsgY6hzEQZ15BdNa13Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19352,13 +19352,13 @@
|
||||
"dependencies": {
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
||||
"dev": true
|
||||
},
|
||||
"iferr": {
|
||||
"version": "0.1.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
|
||||
"dev": true
|
||||
}
|
||||
@@ -19366,13 +19366,13 @@
|
||||
},
|
||||
"get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"dev": true
|
||||
},
|
||||
"get-stream": {
|
||||
"version": "4.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19381,7 +19381,7 @@
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19390,7 +19390,7 @@
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19404,7 +19404,7 @@
|
||||
},
|
||||
"global-dirs": {
|
||||
"version": "0.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19413,7 +19413,7 @@
|
||||
},
|
||||
"got": {
|
||||
"version": "6.7.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19432,7 +19432,7 @@
|
||||
"dependencies": {
|
||||
"get-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
|
||||
"dev": true
|
||||
}
|
||||
@@ -19440,19 +19440,19 @@
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
|
||||
"dev": true
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
|
||||
"dev": true
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "5.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19462,7 +19462,7 @@
|
||||
},
|
||||
"has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19471,37 +19471,37 @@
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||
"dev": true
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
|
||||
"dev": true
|
||||
},
|
||||
"has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
|
||||
"dev": true
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.8",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
|
||||
"dev": true
|
||||
},
|
||||
"http-cache-semantics": {
|
||||
"version": "3.8.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==",
|
||||
"dev": true
|
||||
},
|
||||
"http-proxy-agent": {
|
||||
"version": "2.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19511,7 +19511,7 @@
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19522,7 +19522,7 @@
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "2.2.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19532,7 +19532,7 @@
|
||||
},
|
||||
"humanize-ms": {
|
||||
"version": "1.2.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19541,7 +19541,7 @@
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.23",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19550,13 +19550,13 @@
|
||||
},
|
||||
"iferr": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-9AfeLfji44r5TKInjhz3W9DyZI1zR1JAf2hVBMGhddAKPqBsupb89jGfbCTHIGZd6fGZl9WlHdn4AObygyMKwg==",
|
||||
"dev": true
|
||||
},
|
||||
"ignore-walk": {
|
||||
"version": "3.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19565,25 +19565,25 @@
|
||||
},
|
||||
"import-lazy": {
|
||||
"version": "2.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=",
|
||||
"dev": true
|
||||
},
|
||||
"imurmurhash": {
|
||||
"version": "0.1.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
|
||||
"dev": true
|
||||
},
|
||||
"infer-owner": {
|
||||
"version": "1.0.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
|
||||
"dev": true
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19593,19 +19593,19 @@
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
|
||||
"dev": true
|
||||
},
|
||||
"init-package-json": {
|
||||
"version": "1.10.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-zKSiXKhQveNteyhcj1CoOP8tqp1QuxPIPBl8Bid99DGLFqA1p87M6lNgfjJHSBoWJJlidGOv5rWjyYKEB3g2Jw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19621,25 +19621,25 @@
|
||||
},
|
||||
"ip": {
|
||||
"version": "1.1.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
|
||||
"dev": true
|
||||
},
|
||||
"ip-regex": {
|
||||
"version": "2.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
|
||||
"dev": true
|
||||
},
|
||||
"is-callable": {
|
||||
"version": "1.1.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
|
||||
"dev": true
|
||||
},
|
||||
"is-ci": {
|
||||
"version": "1.2.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19648,7 +19648,7 @@
|
||||
"dependencies": {
|
||||
"ci-info": {
|
||||
"version": "1.6.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==",
|
||||
"dev": true
|
||||
}
|
||||
@@ -19656,7 +19656,7 @@
|
||||
},
|
||||
"is-cidr": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-8Xnnbjsb0x462VoYiGlhEi+drY8SFwrHiSYuzc/CEwco55vkehTaxAyIjEdpi3EMvLPPJAJi9FlzP+h+03gp0Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19665,13 +19665,13 @@
|
||||
},
|
||||
"is-date-object": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
|
||||
"dev": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19680,7 +19680,7 @@
|
||||
},
|
||||
"is-installed-globally": {
|
||||
"version": "0.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19690,19 +19690,19 @@
|
||||
},
|
||||
"is-npm": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=",
|
||||
"dev": true
|
||||
},
|
||||
"is-obj": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
|
||||
"dev": true
|
||||
},
|
||||
"is-path-inside": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19711,13 +19711,13 @@
|
||||
},
|
||||
"is-redirect": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=",
|
||||
"dev": true
|
||||
},
|
||||
"is-regex": {
|
||||
"version": "1.0.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19726,19 +19726,19 @@
|
||||
},
|
||||
"is-retry-allowed": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
|
||||
"dev": true
|
||||
},
|
||||
"is-stream": {
|
||||
"version": "1.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
|
||||
"dev": true
|
||||
},
|
||||
"is-symbol": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19747,68 +19747,68 @@
|
||||
},
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
|
||||
"dev": true
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"dev": true
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
||||
"dev": true
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
|
||||
"dev": true
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"json-parse-better-errors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.3.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
|
||||
"dev": true
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
|
||||
"dev": true
|
||||
},
|
||||
"jsonparse": {
|
||||
"version": "1.3.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
|
||||
"dev": true
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19820,7 +19820,7 @@
|
||||
},
|
||||
"latest-version": {
|
||||
"version": "3.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19829,13 +19829,13 @@
|
||||
},
|
||||
"lazy-property": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-hN3Es3Bnm6i9TNz6TAa0PVcREUc=",
|
||||
"dev": true
|
||||
},
|
||||
"libcipm": {
|
||||
"version": "4.0.8",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-IN3hh2yDJQtZZ5paSV4fbvJg4aHxCCg5tcZID/dSVlTuUiWktsgaldVljJv6Z5OUlYspx6xQkbR0efNodnIrOA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19858,7 +19858,7 @@
|
||||
},
|
||||
"libnpm": {
|
||||
"version": "3.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-d7jU5ZcMiTfBqTUJVZ3xid44fE5ERBm9vBnmhp2ECD2Ls+FNXWxHSkO7gtvrnbLO78gwPdNPz1HpsF3W4rjkBQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19886,7 +19886,7 @@
|
||||
},
|
||||
"libnpmaccess": {
|
||||
"version": "3.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-01512AK7MqByrI2mfC7h5j8N9V4I7MHJuk9buo8Gv+5QgThpOgpjB7sQBDDkeZqRteFb1QM/6YNdHfG7cDvfAQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19898,7 +19898,7 @@
|
||||
},
|
||||
"libnpmconfig": {
|
||||
"version": "1.2.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19909,7 +19909,7 @@
|
||||
"dependencies": {
|
||||
"find-up": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19918,7 +19918,7 @@
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19928,7 +19928,7 @@
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "2.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19937,7 +19937,7 @@
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19946,7 +19946,7 @@
|
||||
},
|
||||
"p-try": {
|
||||
"version": "2.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
||||
"dev": true
|
||||
}
|
||||
@@ -19954,7 +19954,7 @@
|
||||
},
|
||||
"libnpmhook": {
|
||||
"version": "5.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-UdNLMuefVZra/wbnBXECZPefHMGsVDTq5zaM/LgKNE9Keyl5YXQTnGAzEo+nFOpdRqTWI9LYi4ApqF9uVCCtuA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19966,7 +19966,7 @@
|
||||
},
|
||||
"libnpmorg": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-0sRUXLh+PLBgZmARvthhYXQAWn0fOsa6T5l3JSe2n9vKG/lCVK4nuG7pDsa7uMq+uTt2epdPK+a2g6btcY11Ww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19978,7 +19978,7 @@
|
||||
},
|
||||
"libnpmpublish": {
|
||||
"version": "1.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-2yIwaXrhTTcF7bkJKIKmaCV9wZOALf/gsTDxVSu/Gu/6wiG3fA8ce8YKstiWKTxSFNC0R7isPUb6tXTVFZHt2g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -19995,7 +19995,7 @@
|
||||
},
|
||||
"libnpmsearch": {
|
||||
"version": "2.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-VTBbV55Q6fRzTdzziYCr64+f8AopQ1YZ+BdPOv16UegIEaE8C0Kch01wo4s3kRTFV64P121WZJwgmBwrq68zYg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20006,7 +20006,7 @@
|
||||
},
|
||||
"libnpmteam": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-p420vM28Us04NAcg1rzgGW63LMM6rwe+6rtZpfDxCcXxM0zUTLl7nPFEnRF3JfFBF5skF/yuZDUthTsHgde8QA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20018,7 +20018,7 @@
|
||||
},
|
||||
"libnpx": {
|
||||
"version": "10.2.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-BPc0D1cOjBeS8VIBKUu5F80s6njm0wbVt7CsGMrIcJ+SI7pi7V0uVPGpEMH9H5L8csOcclTxAXFE2VAsJXUhfA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20034,7 +20034,7 @@
|
||||
},
|
||||
"lock-verify": {
|
||||
"version": "2.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-vcLpxnGvrqisKvLQ2C2v0/u7LVly17ak2YSgoK4PrdsYBXQIax19vhKiLfvKNFx7FRrpTnitrpzF/uuCMuorIg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20044,7 +20044,7 @@
|
||||
},
|
||||
"lockfile": {
|
||||
"version": "1.0.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20053,13 +20053,13 @@
|
||||
},
|
||||
"lodash._baseindexof": {
|
||||
"version": "3.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash._baseuniq": {
|
||||
"version": "4.6.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-DrtE5FaBSveQXGIS+iybLVG4Qeg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20069,19 +20069,19 @@
|
||||
},
|
||||
"lodash._bindcallback": {
|
||||
"version": "3.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash._cacheindexof": {
|
||||
"version": "3.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash._createcache": {
|
||||
"version": "3.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-VtagZAF2JeeevKa4AY4XRAvc8JM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20090,61 +20090,61 @@
|
||||
},
|
||||
"lodash._createset": {
|
||||
"version": "4.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash._getnative": {
|
||||
"version": "3.9.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash._root": {
|
||||
"version": "3.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.clonedeep": {
|
||||
"version": "4.5.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.restparam": {
|
||||
"version": "3.6.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.union": {
|
||||
"version": "4.6.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.uniq": {
|
||||
"version": "4.5.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.without": {
|
||||
"version": "4.4.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-PNRXSgC2e643OpS3SHcmQFB7eqw=",
|
||||
"dev": true
|
||||
},
|
||||
"lowercase-keys": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
|
||||
"dev": true
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "5.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20153,7 +20153,7 @@
|
||||
},
|
||||
"make-dir": {
|
||||
"version": "1.3.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20162,7 +20162,7 @@
|
||||
},
|
||||
"make-fetch-happen": {
|
||||
"version": "5.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20181,19 +20181,19 @@
|
||||
},
|
||||
"meant": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-KN+1uowN/NK+sT/Lzx7WSGIj2u+3xe5n2LbwObfjOhPZiA+cCfCm6idVl0RkEfjThkw5XJ96CyRcanq6GmKtUg==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.35.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.19",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20202,7 +20202,7 @@
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20211,13 +20211,13 @@
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||
"dev": true
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "1.3.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20226,7 +20226,7 @@
|
||||
"dependencies": {
|
||||
"minipass": {
|
||||
"version": "2.9.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20238,7 +20238,7 @@
|
||||
},
|
||||
"mississippi": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20256,7 +20256,7 @@
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20265,7 +20265,7 @@
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||
"dev": true
|
||||
}
|
||||
@@ -20273,7 +20273,7 @@
|
||||
},
|
||||
"move-concurrently": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20287,7 +20287,7 @@
|
||||
"dependencies": {
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
||||
"dev": true
|
||||
}
|
||||
@@ -20295,19 +20295,19 @@
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
|
||||
"dev": true
|
||||
},
|
||||
"mute-stream": {
|
||||
"version": "0.0.7",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
|
||||
"dev": true
|
||||
},
|
||||
"node-fetch-npm": {
|
||||
"version": "2.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-nJIxm1QmAj4v3nfCvEeCrYSoVwXyxLnaPBK5W1W5DGEJwjlKuC2VEUycGw5oxk+4zZahRrB84PUJJgEmhFTDFw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20318,7 +20318,7 @@
|
||||
},
|
||||
"node-gyp": {
|
||||
"version": "5.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-OUTryc5bt/P8zVgNUmC6xdXiDJxLMAW8cF5tLQOT9E5sOQj+UeQxnnPy74K3CLCa/SOjjBlbuzDLR8ANwA+wmw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20337,7 +20337,7 @@
|
||||
},
|
||||
"nopt": {
|
||||
"version": "4.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20347,7 +20347,7 @@
|
||||
},
|
||||
"normalize-package-data": {
|
||||
"version": "2.5.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20359,7 +20359,7 @@
|
||||
"dependencies": {
|
||||
"resolve": {
|
||||
"version": "1.10.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20370,7 +20370,7 @@
|
||||
},
|
||||
"npm-audit-report": {
|
||||
"version": "1.3.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-8nH/JjsFfAWMvn474HB9mpmMjrnKb1Hx/oTAdjv4PT9iZBvBxiZ+wtDUapHCJwLqYGQVPaAfs+vL5+5k9QndXw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20380,7 +20380,7 @@
|
||||
},
|
||||
"npm-bundled": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20389,13 +20389,13 @@
|
||||
},
|
||||
"npm-cache-filename": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE=",
|
||||
"dev": true
|
||||
},
|
||||
"npm-install-checks": {
|
||||
"version": "3.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-E4kzkyZDIWoin6uT5howP8VDvkM+E8IQDcHAycaAxMbwkqhIg5eEYALnXOl3Hq9MrkdQB/2/g1xwBINXdKSRkg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20404,7 +20404,7 @@
|
||||
},
|
||||
"npm-lifecycle": {
|
||||
"version": "3.1.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-lDLVkjfZmvmfvpvBzA4vzee9cn+Me4orq0QF8glbswJVEbIcSNWib7qGOffolysc3teCqbbPZZkzbr3GQZTL1g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20420,19 +20420,19 @@
|
||||
},
|
||||
"npm-logical-tree": {
|
||||
"version": "1.2.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-AJI/qxDB2PWI4LG1CYN579AY1vCiNyWfkiquCsJWqntRu/WwimVrC8yXeILBFHDwxfOejxewlmnvW9XXjMlYIg==",
|
||||
"dev": true
|
||||
},
|
||||
"npm-normalize-package-bin": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==",
|
||||
"dev": true
|
||||
},
|
||||
"npm-package-arg": {
|
||||
"version": "6.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20444,7 +20444,7 @@
|
||||
},
|
||||
"npm-packlist": {
|
||||
"version": "1.4.8",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20455,7 +20455,7 @@
|
||||
},
|
||||
"npm-pick-manifest": {
|
||||
"version": "3.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20466,7 +20466,7 @@
|
||||
},
|
||||
"npm-profile": {
|
||||
"version": "4.0.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-Ta8xq8TLMpqssF0H60BXS1A90iMoM6GeKwsmravJ6wYjWwSzcYBTdyWa3DZCYqPutacBMEm7cxiOkiIeCUAHDQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20477,7 +20477,7 @@
|
||||
},
|
||||
"npm-registry-fetch": {
|
||||
"version": "4.0.7",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-cny9v0+Mq6Tjz+e0erFAB+RYJ/AVGzkjnISiobqP8OWj9c9FLoZZu8/SPSKJWE17F1tk4018wfjV+ZbIbqC7fQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20492,7 +20492,7 @@
|
||||
"dependencies": {
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"dev": true
|
||||
}
|
||||
@@ -20500,7 +20500,7 @@
|
||||
},
|
||||
"npm-run-path": {
|
||||
"version": "2.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20509,13 +20509,13 @@
|
||||
},
|
||||
"npm-user-validate": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-jOyg9c6gTU6TUZ73LQVXp1Ei6VE=",
|
||||
"dev": true
|
||||
},
|
||||
"npmlog": {
|
||||
"version": "4.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20527,31 +20527,31 @@
|
||||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
||||
"dev": true
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
|
||||
"dev": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"dev": true
|
||||
},
|
||||
"object-keys": {
|
||||
"version": "1.0.12",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==",
|
||||
"dev": true
|
||||
},
|
||||
"object.getownpropertydescriptors": {
|
||||
"version": "2.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20561,7 +20561,7 @@
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20570,25 +20570,25 @@
|
||||
},
|
||||
"opener": {
|
||||
"version": "1.5.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==",
|
||||
"dev": true
|
||||
},
|
||||
"os-homedir": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
|
||||
"dev": true
|
||||
},
|
||||
"os-tmpdir": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
|
||||
"dev": true
|
||||
},
|
||||
"osenv": {
|
||||
"version": "0.1.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20598,13 +20598,13 @@
|
||||
},
|
||||
"p-finally": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
|
||||
"dev": true
|
||||
},
|
||||
"package-json": {
|
||||
"version": "4.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20616,7 +20616,7 @@
|
||||
},
|
||||
"pacote": {
|
||||
"version": "9.5.12",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-BUIj/4kKbwWg4RtnBncXPJd15piFSVNpTzY0rysSr3VnMowTYgkGKcaHrbReepAkjTr8lH2CVWRi58Spg2CicQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20654,7 +20654,7 @@
|
||||
"dependencies": {
|
||||
"minipass": {
|
||||
"version": "2.9.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20666,7 +20666,7 @@
|
||||
},
|
||||
"parallel-transform": {
|
||||
"version": "1.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20677,7 +20677,7 @@
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20692,7 +20692,7 @@
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20703,67 +20703,67 @@
|
||||
},
|
||||
"path-exists": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
|
||||
"dev": true
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
},
|
||||
"path-is-inside": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
|
||||
"dev": true
|
||||
},
|
||||
"path-key": {
|
||||
"version": "2.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
|
||||
"dev": true
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
|
||||
"dev": true
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "2.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
|
||||
"dev": true
|
||||
},
|
||||
"pify": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
|
||||
"dev": true
|
||||
},
|
||||
"prepend-http": {
|
||||
"version": "1.0.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
|
||||
"dev": true
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
|
||||
"dev": true
|
||||
},
|
||||
"promise-inflight": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
|
||||
"dev": true
|
||||
},
|
||||
"promise-retry": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20773,7 +20773,7 @@
|
||||
"dependencies": {
|
||||
"retry": {
|
||||
"version": "0.10.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=",
|
||||
"dev": true
|
||||
}
|
||||
@@ -20781,7 +20781,7 @@
|
||||
},
|
||||
"promzard": {
|
||||
"version": "0.3.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-JqXW7ox97kyxIggwWs+5O6OCqe4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20790,13 +20790,13 @@
|
||||
},
|
||||
"proto-list": {
|
||||
"version": "1.2.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=",
|
||||
"dev": true
|
||||
},
|
||||
"protoduck": {
|
||||
"version": "5.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20805,25 +20805,25 @@
|
||||
},
|
||||
"prr": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
|
||||
"dev": true
|
||||
},
|
||||
"pseudomap": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
|
||||
"dev": true
|
||||
},
|
||||
"psl": {
|
||||
"version": "1.1.29",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==",
|
||||
"dev": true
|
||||
},
|
||||
"pump": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20833,7 +20833,7 @@
|
||||
},
|
||||
"pumpify": {
|
||||
"version": "1.5.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20844,7 +20844,7 @@
|
||||
"dependencies": {
|
||||
"pump": {
|
||||
"version": "2.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20856,25 +20856,25 @@
|
||||
},
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
|
||||
"dev": true
|
||||
},
|
||||
"qrcode-terminal": {
|
||||
"version": "0.12.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==",
|
||||
"dev": true
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
|
||||
"dev": true
|
||||
},
|
||||
"query-string": {
|
||||
"version": "6.8.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-J3Qi8XZJXh93t2FiKyd/7Ec6GNifsjKXUsVFkSBj/kjLsDylWhnCz4NT1bkPcKotttPW+QbKGqqPH8OoI2pdqw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20885,13 +20885,13 @@
|
||||
},
|
||||
"qw": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-77/cdA+a0FQwRCassYNBLMi5ltQ=",
|
||||
"dev": true
|
||||
},
|
||||
"rc": {
|
||||
"version": "1.2.8",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20903,7 +20903,7 @@
|
||||
},
|
||||
"read": {
|
||||
"version": "1.0.7",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20912,7 +20912,7 @@
|
||||
},
|
||||
"read-cmd-shim": {
|
||||
"version": "1.0.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-v5yCqQ/7okKoZZkBQUAfTsQ3sVJtXdNfbPnI5cceppoxEVLYA3k+VtV2omkeo8MS94JCy4fSiUwlRBAwCVRPUA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20921,7 +20921,7 @@
|
||||
},
|
||||
"read-installed": {
|
||||
"version": "4.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20936,7 +20936,7 @@
|
||||
},
|
||||
"read-package-json": {
|
||||
"version": "2.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-dAiqGtVc/q5doFz6096CcnXhpYk0ZN8dEKVkGLU0CsASt8SrgF6SF7OTKAYubfvFhWaqofl+Y8HK19GR8jwW+A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20949,7 +20949,7 @@
|
||||
},
|
||||
"read-package-tree": {
|
||||
"version": "5.3.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20960,7 +20960,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20971,7 +20971,7 @@
|
||||
},
|
||||
"readdir-scoped-modules": {
|
||||
"version": "1.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20983,7 +20983,7 @@
|
||||
},
|
||||
"registry-auth-token": {
|
||||
"version": "3.4.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -20993,7 +20993,7 @@
|
||||
},
|
||||
"registry-url": {
|
||||
"version": "3.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21002,7 +21002,7 @@
|
||||
},
|
||||
"request": {
|
||||
"version": "2.88.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21030,31 +21030,31 @@
|
||||
},
|
||||
"require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
|
||||
"dev": true
|
||||
},
|
||||
"require-main-filename": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
||||
"dev": true
|
||||
},
|
||||
"resolve-from": {
|
||||
"version": "4.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
|
||||
"dev": true
|
||||
},
|
||||
"retry": {
|
||||
"version": "0.12.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
|
||||
"dev": true
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.7.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21063,7 +21063,7 @@
|
||||
},
|
||||
"run-queue": {
|
||||
"version": "1.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21072,7 +21072,7 @@
|
||||
"dependencies": {
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
||||
"dev": true
|
||||
}
|
||||
@@ -21080,25 +21080,25 @@
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"dev": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||
"dev": true
|
||||
},
|
||||
"semver-diff": {
|
||||
"version": "2.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21107,13 +21107,13 @@
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
|
||||
"dev": true
|
||||
},
|
||||
"sha": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-DOYnM37cNsLNSGIG/zZWch5CKIRNoLdYUQTQlcgkRkoYIUwDYjqDyye16YcDZg/OPdcbUgTKMjc4SY6TB7ZAPw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21122,7 +21122,7 @@
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21131,31 +21131,31 @@
|
||||
},
|
||||
"shebang-regex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
|
||||
"dev": true
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
|
||||
"dev": true
|
||||
},
|
||||
"slide": {
|
||||
"version": "1.1.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=",
|
||||
"dev": true
|
||||
},
|
||||
"smart-buffer": {
|
||||
"version": "4.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==",
|
||||
"dev": true
|
||||
},
|
||||
"socks": {
|
||||
"version": "2.3.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21165,7 +21165,7 @@
|
||||
},
|
||||
"socks-proxy-agent": {
|
||||
"version": "4.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21175,7 +21175,7 @@
|
||||
"dependencies": {
|
||||
"agent-base": {
|
||||
"version": "4.2.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21186,13 +21186,13 @@
|
||||
},
|
||||
"sorted-object": {
|
||||
"version": "2.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-fWMfS9OnmKJK8d/8+/6DM3pd9fw=",
|
||||
"dev": true
|
||||
},
|
||||
"sorted-union-stream": {
|
||||
"version": "2.1.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-x3lMfgd4gAUv9xqNSi27Sppjisc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21202,7 +21202,7 @@
|
||||
"dependencies": {
|
||||
"from2": {
|
||||
"version": "1.3.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-iEE7qqX5pZfP3pIh2GmGzTwGHf0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21212,13 +21212,13 @@
|
||||
},
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
|
||||
"dev": true
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "1.1.14",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21230,7 +21230,7 @@
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
|
||||
"dev": true
|
||||
}
|
||||
@@ -21238,7 +21238,7 @@
|
||||
},
|
||||
"spdx-correct": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21248,13 +21248,13 @@
|
||||
},
|
||||
"spdx-exceptions": {
|
||||
"version": "2.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==",
|
||||
"dev": true
|
||||
},
|
||||
"spdx-expression-parse": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21264,19 +21264,19 @@
|
||||
},
|
||||
"spdx-license-ids": {
|
||||
"version": "3.0.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"split-on-first": {
|
||||
"version": "1.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
|
||||
"dev": true
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.14.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21293,7 +21293,7 @@
|
||||
},
|
||||
"ssri": {
|
||||
"version": "6.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21302,7 +21302,7 @@
|
||||
},
|
||||
"stream-each": {
|
||||
"version": "1.2.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21312,7 +21312,7 @@
|
||||
},
|
||||
"stream-iterate": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-K9fHcpbBcCpGSIuK1B95hl7s1OE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21322,7 +21322,7 @@
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21337,7 +21337,7 @@
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21348,19 +21348,19 @@
|
||||
},
|
||||
"stream-shift": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
|
||||
"dev": true
|
||||
},
|
||||
"strict-uri-encode": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=",
|
||||
"dev": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "2.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21370,19 +21370,19 @@
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
|
||||
"dev": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
|
||||
"dev": true
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "4.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21393,7 +21393,7 @@
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21402,7 +21402,7 @@
|
||||
"dependencies": {
|
||||
"safe-buffer": {
|
||||
"version": "5.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
|
||||
"dev": true
|
||||
}
|
||||
@@ -21410,13 +21410,13 @@
|
||||
},
|
||||
"stringify-package": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==",
|
||||
"dev": true
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21425,19 +21425,19 @@
|
||||
},
|
||||
"strip-eof": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
|
||||
"dev": true
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.4.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21446,7 +21446,7 @@
|
||||
},
|
||||
"tar": {
|
||||
"version": "4.4.13",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21461,7 +21461,7 @@
|
||||
"dependencies": {
|
||||
"minipass": {
|
||||
"version": "2.9.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21473,7 +21473,7 @@
|
||||
},
|
||||
"term-size": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21482,19 +21482,19 @@
|
||||
},
|
||||
"text-table": {
|
||||
"version": "0.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
|
||||
"dev": true
|
||||
},
|
||||
"through": {
|
||||
"version": "2.3.8",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
|
||||
"dev": true
|
||||
},
|
||||
"through2": {
|
||||
"version": "2.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21504,7 +21504,7 @@
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21519,7 +21519,7 @@
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21530,19 +21530,19 @@
|
||||
},
|
||||
"timed-out": {
|
||||
"version": "4.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
|
||||
"dev": true
|
||||
},
|
||||
"tiny-relative-date": {
|
||||
"version": "1.3.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A==",
|
||||
"dev": true
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.4.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21552,7 +21552,7 @@
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21561,32 +21561,32 @@
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
|
||||
"dev": true
|
||||
},
|
||||
"uid-number": {
|
||||
"version": "0.0.6",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=",
|
||||
"dev": true
|
||||
},
|
||||
"umask": {
|
||||
"version": "1.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0=",
|
||||
"dev": true
|
||||
},
|
||||
"unique-filename": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21595,7 +21595,7 @@
|
||||
},
|
||||
"unique-slug": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21604,7 +21604,7 @@
|
||||
},
|
||||
"unique-string": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21613,19 +21613,19 @@
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
|
||||
"dev": true
|
||||
},
|
||||
"unzip-response": {
|
||||
"version": "2.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=",
|
||||
"dev": true
|
||||
},
|
||||
"update-notifier": {
|
||||
"version": "2.5.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21643,7 +21643,7 @@
|
||||
},
|
||||
"url-parse-lax": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21652,19 +21652,19 @@
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"dev": true
|
||||
},
|
||||
"util-extend": {
|
||||
"version": "1.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=",
|
||||
"dev": true
|
||||
},
|
||||
"util-promisify": {
|
||||
"version": "2.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-PCI2R2xNMsX/PEcAKt18E7moKlM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21673,13 +21673,13 @@
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.3.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==",
|
||||
"dev": true
|
||||
},
|
||||
"validate-npm-package-license": {
|
||||
"version": "3.0.4",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21689,7 +21689,7 @@
|
||||
},
|
||||
"validate-npm-package-name": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21698,7 +21698,7 @@
|
||||
},
|
||||
"verror": {
|
||||
"version": "1.10.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21709,7 +21709,7 @@
|
||||
},
|
||||
"wcwidth": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21718,7 +21718,7 @@
|
||||
},
|
||||
"which": {
|
||||
"version": "1.3.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21727,13 +21727,13 @@
|
||||
},
|
||||
"which-module": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
|
||||
"dev": true
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21742,7 +21742,7 @@
|
||||
"dependencies": {
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21755,7 +21755,7 @@
|
||||
},
|
||||
"widest-line": {
|
||||
"version": "2.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21764,7 +21764,7 @@
|
||||
},
|
||||
"worker-farm": {
|
||||
"version": "1.7.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21773,7 +21773,7 @@
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "5.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21784,19 +21784,19 @@
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"dev": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
|
||||
"dev": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "3.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21807,7 +21807,7 @@
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "5.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21818,13 +21818,13 @@
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
},
|
||||
"write-file-atomic": {
|
||||
"version": "2.4.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21835,31 +21835,31 @@
|
||||
},
|
||||
"xdg-basedir": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=",
|
||||
"dev": true
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
|
||||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "14.2.3",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21878,13 +21878,13 @@
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"dev": true
|
||||
},
|
||||
"find-up": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21893,13 +21893,13 @@
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
|
||||
"dev": true
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21909,7 +21909,7 @@
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "2.3.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21918,7 +21918,7 @@
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "3.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21927,13 +21927,13 @@
|
||||
},
|
||||
"p-try": {
|
||||
"version": "2.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
||||
"dev": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "3.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21944,7 +21944,7 @@
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "5.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21955,7 +21955,7 @@
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "15.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -21965,7 +21965,7 @@
|
||||
"dependencies": {
|
||||
"camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": false,
|
||||
"resolved": "",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
||||
"dev": true
|
||||
}
|
||||
@@ -24779,6 +24779,12 @@
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"reactifex": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/reactifex/-/reactifex-1.1.1.tgz",
|
||||
"integrity": "sha512-HH2N/b5tRxh7ypIgCRsiBl/CTxRkTEPf9DhIstaM6hne4WiwM5/bBbWuvVlRZc/i3FdqZED3pZ//6n4mtxma4w==",
|
||||
"dev": true
|
||||
},
|
||||
"read-pkg": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@edx/frontend-app-gradebook",
|
||||
"version": "1.4.39",
|
||||
"version": "1.4.46",
|
||||
"description": "edx editable gradebook-ui to manipulate grade overrides on subsections",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -10,6 +10,7 @@
|
||||
"build": "fedx-scripts webpack",
|
||||
"coveralls": "cat ./coverage/lcov.info | coveralls",
|
||||
"is-es5": "es-check es5 ./dist/*.js",
|
||||
"i18n_extract": "BABEL_ENV=i18n fedx-scripts babel src --quiet > /dev/null",
|
||||
"lint": "fedx-scripts eslint --ext .jsx,.js src/",
|
||||
"lint-fix": "fedx-scripts eslint --fix --ext .jsx,.js src/",
|
||||
"prepush": "npm run lint",
|
||||
@@ -75,6 +76,7 @@
|
||||
"jest": "24.9.0",
|
||||
"react-dev-utils": "^5.0.3",
|
||||
"react-test-renderer": "^16.10.1",
|
||||
"reactifex": "1.1.1",
|
||||
"redux-mock-store": "^1.5.3",
|
||||
"semantic-release": "^17.2.3",
|
||||
"travis-deploy-once": "^5.0.11"
|
||||
|
||||
36
src/App.jsx
Executable file
36
src/App.jsx
Executable file
@@ -0,0 +1,36 @@
|
||||
import React from 'react';
|
||||
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
|
||||
import { Provider } from 'react-redux';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
|
||||
import Footer from '@edx/frontend-component-footer';
|
||||
|
||||
import { routePath } from 'data/constants/app';
|
||||
import store from 'data/store';
|
||||
import GradebookPage from 'containers/GradebookPage';
|
||||
import EdxHeader from 'components/EdxHeader';
|
||||
import './App.scss';
|
||||
|
||||
const App = () => (
|
||||
<IntlProvider locale="en">
|
||||
<Provider store={store}>
|
||||
<Router>
|
||||
<div>
|
||||
<EdxHeader />
|
||||
<main>
|
||||
<Switch>
|
||||
<Route
|
||||
exact
|
||||
path={routePath}
|
||||
component={GradebookPage}
|
||||
/>
|
||||
</Switch>
|
||||
</main>
|
||||
<Footer logo={process.env.LOGO_POWERED_BY_OPEN_EDX_URL_SVG} />
|
||||
</div>
|
||||
</Router>
|
||||
</Provider>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
export default App;
|
||||
86
src/App.test.jsx
Normal file
86
src/App.test.jsx
Normal file
@@ -0,0 +1,86 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
|
||||
import { Provider } from 'react-redux';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
|
||||
import Footer from '@edx/frontend-component-footer';
|
||||
|
||||
import { routePath } from 'data/constants/app';
|
||||
import store from 'data/store';
|
||||
import GradebookPage from 'containers/GradebookPage';
|
||||
import EdxHeader from 'components/EdxHeader';
|
||||
|
||||
import App from './App';
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
BrowserRouter: () => 'BrowserRouter',
|
||||
Route: () => 'Route',
|
||||
Switch: () => 'Switch',
|
||||
}));
|
||||
jest.mock('react-redux', () => ({
|
||||
Provider: () => 'Provider',
|
||||
}));
|
||||
jest.mock('react-intl', () => ({
|
||||
IntlProvider: () => 'IntlProvider',
|
||||
}));
|
||||
jest.mock('data/constants/app', () => ({
|
||||
routePath: '/:courseId',
|
||||
}));
|
||||
jest.mock('@edx/frontend-component-footer', () => 'Footer');
|
||||
jest.mock('data/store', () => 'testStore');
|
||||
jest.mock('containers/GradebookPage', () => 'GradebookPage');
|
||||
jest.mock('components/EdxHeader', () => 'EdxHeader');
|
||||
|
||||
const logo = 'fakeLogo.png';
|
||||
let el;
|
||||
let router;
|
||||
|
||||
describe('App router component', () => {
|
||||
test('snapshot', () => {
|
||||
expect(shallow(<App />)).toMatchSnapshot();
|
||||
});
|
||||
describe('component', () => {
|
||||
beforeEach(() => {
|
||||
process.env.LOGO_POWERED_BY_OPEN_EDX_URL_SVG = logo;
|
||||
el = shallow(<App />);
|
||||
router = el.childAt(0).childAt(0);
|
||||
});
|
||||
describe('IntlProvider', () => {
|
||||
test('outer-wrapper component', () => {
|
||||
expect(el.type()).toBe(IntlProvider);
|
||||
});
|
||||
test('"en" locale', () => {
|
||||
expect(el.props().locale).toEqual('en');
|
||||
});
|
||||
});
|
||||
describe('Provider, inside IntlProvider', () => {
|
||||
test('first child, passed the redux store props', () => {
|
||||
expect(el.childAt(0).type()).toBe(Provider);
|
||||
expect(el.childAt(0).props().store).toEqual(store);
|
||||
});
|
||||
});
|
||||
describe('Router', () => {
|
||||
test('first child of Provider', () => {
|
||||
expect(router.type()).toBe(Router);
|
||||
});
|
||||
test('EdxHeader is above/outside-of the routing', () => {
|
||||
expect(router.childAt(0).childAt(0).type()).toBe(EdxHeader);
|
||||
expect(router.childAt(0).childAt(1).type()).toBe('main');
|
||||
});
|
||||
test('Routing - GradebookPage is only route', () => {
|
||||
expect(router.find('main')).toEqual(shallow(
|
||||
<main>
|
||||
<Switch>
|
||||
<Route exact path={routePath} component={GradebookPage} />
|
||||
</Switch>
|
||||
</main>,
|
||||
));
|
||||
});
|
||||
});
|
||||
test('Footer logo drawn from env variable', () => {
|
||||
expect(router.find(Footer).props().logo).toEqual(logo);
|
||||
});
|
||||
});
|
||||
});
|
||||
27
src/__snapshots__/App.test.jsx.snap
Normal file
27
src/__snapshots__/App.test.jsx.snap
Normal file
@@ -0,0 +1,27 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`App router component snapshot 1`] = `
|
||||
<IntlProvider
|
||||
locale="en"
|
||||
>
|
||||
<Provider
|
||||
store="testStore"
|
||||
>
|
||||
<BrowserRouter>
|
||||
<div>
|
||||
<EdxHeader />
|
||||
<main>
|
||||
<Switch>
|
||||
<Route
|
||||
component="GradebookPage"
|
||||
exact={true}
|
||||
path="/:courseId"
|
||||
/>
|
||||
</Switch>
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
</BrowserRouter>
|
||||
</Provider>
|
||||
</IntlProvider>
|
||||
`;
|
||||
@@ -1,20 +1,22 @@
|
||||
/* eslint-disable react/sort-comp, react/button-has-type */
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { Alert } from '@edx/paragon';
|
||||
|
||||
import * as appConstants from 'data/constants/app';
|
||||
import selectors from 'data/selectors';
|
||||
|
||||
const { messages: { BulkManagementTab: messages } } = appConstants;
|
||||
import messages from './messages';
|
||||
|
||||
/**
|
||||
* <BulkManagementAlerts />
|
||||
* Alerts to display at the top of the BulkManagement tab
|
||||
*/
|
||||
export const BulkManagementAlerts = ({ bulkImportError, uploadSuccess }) => (
|
||||
export const BulkManagementAlerts = ({
|
||||
bulkImportError,
|
||||
uploadSuccess,
|
||||
}) => (
|
||||
<>
|
||||
<Alert
|
||||
variant="danger"
|
||||
@@ -28,7 +30,7 @@ export const BulkManagementAlerts = ({ bulkImportError, uploadSuccess }) => (
|
||||
show={uploadSuccess}
|
||||
dismissible={false}
|
||||
>
|
||||
{messages.successDialog}
|
||||
<FormattedMessage {...messages.successDialog} />
|
||||
</Alert>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { Alert } from '@edx/paragon';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import selectors from 'data/selectors';
|
||||
import * as appConstants from 'data/constants/app';
|
||||
import messages from './messages';
|
||||
|
||||
import { BulkManagementAlerts, mapStateToProps } from './BulkManagementAlerts';
|
||||
|
||||
jest.mock('@edx/frontend-platform/i18n', () => ({
|
||||
defineMessages: m => m,
|
||||
FormattedMessage: () => 'FormattedMessage',
|
||||
}));
|
||||
jest.mock('@edx/paragon', () => ({
|
||||
Alert: () => 'Alert',
|
||||
}));
|
||||
@@ -61,8 +66,8 @@ describe('BulkManagementAlerts', () => {
|
||||
});
|
||||
test('open success alert with messages.successDialog content', () => {
|
||||
expect(el.childAt(1).is(Alert)).toEqual(true);
|
||||
expect(el.childAt(1).children().text()).toEqual(
|
||||
appConstants.messages.BulkManagementTab.successDialog,
|
||||
expect(el.childAt(1).children().getElement()).toEqual(
|
||||
<FormattedMessage {...messages.successDialog} />,
|
||||
);
|
||||
expect(el.childAt(1).props().show).toEqual(true);
|
||||
});
|
||||
|
||||
@@ -3,6 +3,8 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import {
|
||||
Button,
|
||||
Form,
|
||||
@@ -10,11 +12,9 @@ import {
|
||||
FormGroup,
|
||||
} from '@edx/paragon';
|
||||
|
||||
import { messages } from 'data/constants/app';
|
||||
import selectors from 'data/selectors';
|
||||
import thunkActions from 'data/thunkActions';
|
||||
|
||||
const { csvUploadLabel, importBtnText } = messages.BulkManagementTab;
|
||||
import messages from './messages';
|
||||
|
||||
/**
|
||||
* <FileUploadForm />
|
||||
@@ -56,14 +56,15 @@ export class FileUploadForm extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { gradeExportUrl } = this.props;
|
||||
return (
|
||||
<>
|
||||
<Form action={this.props.gradeExportUrl} method="post">
|
||||
<Form action={gradeExportUrl} method="post">
|
||||
<FormGroup controlId="csv">
|
||||
<FormControl
|
||||
className="d-none"
|
||||
type="file"
|
||||
label={csvUploadLabel}
|
||||
label={<FormattedMessage {...messages.csvUploadLabel} />}
|
||||
onChange={this.handleFileInputChange}
|
||||
ref={this.fileInputRef}
|
||||
/>
|
||||
@@ -71,7 +72,7 @@ export class FileUploadForm extends React.Component {
|
||||
</Form>
|
||||
|
||||
<Button variant="primary" onClick={this.handleClickImportGrades}>
|
||||
{importBtnText}
|
||||
<FormattedMessage {...messages.importBtnText} />
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
/* eslint-disable import/no-named-as-default */
|
||||
import React from 'react';
|
||||
import { shallow, mount } from 'enzyme';
|
||||
import { shallow } from 'enzyme';
|
||||
import TestRenderer from 'react-test-renderer';
|
||||
import {
|
||||
Button,
|
||||
Form,
|
||||
FormControl,
|
||||
FormGroup,
|
||||
} from '@edx/paragon';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import selectors from 'data/selectors';
|
||||
import thunkActions from 'data/thunkActions';
|
||||
import * as appConstants from 'data/constants/app';
|
||||
|
||||
import { FileUploadForm, mapStateToProps, mapDispatchToProps } from './FileUploadForm';
|
||||
|
||||
const {
|
||||
messages: { BulkManagementTab: messages },
|
||||
} = appConstants;
|
||||
import messages from './messages';
|
||||
|
||||
jest.mock('@edx/frontend-platform/i18n', () => ({
|
||||
defineMessages: m => m,
|
||||
FormattedMessage: () => 'FormattedMessage',
|
||||
}));
|
||||
jest.mock('data/selectors', () => ({
|
||||
__esModule: true,
|
||||
default: {
|
||||
@@ -39,10 +41,16 @@ jest.mock('data/thunkActions', () => ({
|
||||
jest.mock('./BulkManagementAlerts', () => 'BulkManagementAlerts');
|
||||
jest.mock('./ResultsSummary', () => 'ResultsSummary');
|
||||
|
||||
const mockRef = { click: jest.fn(), files: [] };
|
||||
|
||||
describe('FileUploadForm', () => {
|
||||
beforeEach(() => {
|
||||
mockRef.click.mockClear();
|
||||
});
|
||||
describe('component', () => {
|
||||
let props;
|
||||
let el;
|
||||
let inst;
|
||||
beforeEach(() => {
|
||||
props = {
|
||||
gradeExportUrl: 'fakeUrl',
|
||||
@@ -71,87 +79,105 @@ describe('FileUploadForm', () => {
|
||||
});
|
||||
describe('render', () => {
|
||||
beforeEach(() => {
|
||||
el = mount(<FileUploadForm {...props} />);
|
||||
el = TestRenderer.create(
|
||||
<FileUploadForm {...props} />,
|
||||
{ createNodeMock: () => mockRef },
|
||||
);
|
||||
inst = el.root;
|
||||
});
|
||||
describe('alert form', () => {
|
||||
let form;
|
||||
beforeEach(() => {
|
||||
form = el.find(Form);
|
||||
form = inst.findByType(Form);
|
||||
});
|
||||
test('post action points to gradeExportUrl', () => {
|
||||
expect(form.props().action).toEqual(props.gradeExportUrl);
|
||||
expect(form.props().method).toEqual('post');
|
||||
expect(form.props.action).toEqual(props.gradeExportUrl);
|
||||
expect(form.props.method).toEqual('post');
|
||||
});
|
||||
describe('file input', () => {
|
||||
let formGroup;
|
||||
beforeEach(() => {
|
||||
formGroup = el.find(FormGroup);
|
||||
formGroup = inst.findByType(FormGroup);
|
||||
});
|
||||
test('group with controlId="csv"', () => {
|
||||
expect(formGroup.props().controlId).toEqual('csv');
|
||||
expect(formGroup.props.controlId).toEqual('csv');
|
||||
});
|
||||
test('file control with onChange from handleFileInputChange', () => {
|
||||
const control = el.find(FormControl);
|
||||
const control = inst.findByType(FormControl);
|
||||
expect(
|
||||
control.props().onChange,
|
||||
).toEqual(el.instance().handleFileInputChange);
|
||||
control.props.onChange,
|
||||
).toEqual(el.getInstance().handleFileInputChange);
|
||||
});
|
||||
test('fileInputRef points to control', () => {
|
||||
expect(el.find(FormControl).getElement().ref).toBe(el.instance().fileInputRef);
|
||||
expect(
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
inst.findByType(FormControl)._fiber.ref,
|
||||
).toEqual(el.getInstance().fileInputRef);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('import button', () => {
|
||||
let btn;
|
||||
beforeEach(() => {
|
||||
btn = el.find(Button);
|
||||
btn = inst.findByType(Button);
|
||||
});
|
||||
test('handleClickImportGrade on click', () => {
|
||||
expect(btn.props().onClick).toEqual(el.instance().handleClickImportGrades);
|
||||
expect(btn.props.onClick).toEqual(el.getInstance().handleClickImportGrades);
|
||||
});
|
||||
test('text from messages.importBtn', () => {
|
||||
expect(btn.children().text()).toEqual(messages.importBtnText);
|
||||
const messageEl = btn.findByType(FormattedMessage);
|
||||
expect(messageEl.props).toEqual(messages.importBtnText);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('fileInput helper', () => {
|
||||
test('links to fileInputRef.current', () => {
|
||||
el = TestRenderer.create(
|
||||
<FileUploadForm {...props} />,
|
||||
{ createNodeMock: () => mockRef },
|
||||
);
|
||||
expect(el.getInstance().fileInput).not.toEqual(undefined);
|
||||
expect(el.getInstance().fileInput).toEqual(el.getInstance().fileInputRef.current);
|
||||
});
|
||||
});
|
||||
describe('behavior', () => {
|
||||
let fileInput;
|
||||
beforeEach(() => {
|
||||
el = mount(<FileUploadForm {...props} />);
|
||||
fileInput = jest.spyOn(el.instance(), 'fileInput', 'get');
|
||||
el = TestRenderer.create(
|
||||
<FileUploadForm {...props} />,
|
||||
{ createNodeMock: () => mockRef },
|
||||
);
|
||||
fileInput = jest.spyOn(el.getInstance(), 'fileInput', 'get');
|
||||
});
|
||||
describe('handleFileInputChange', () => {
|
||||
it('does nothing (does not fail) if fileInput has not loaded', () => {
|
||||
fileInput.mockReturnValue(null);
|
||||
el.instance().handleClickImportGrades();
|
||||
el.getInstance().handleClickImportGrades();
|
||||
expect(mockRef.click).not.toHaveBeenCalled();
|
||||
});
|
||||
it('calls fileInput.click if is loaded', () => {
|
||||
const click = jest.fn();
|
||||
fileInput.mockReturnValue({ click });
|
||||
el.instance().handleClickImportGrades();
|
||||
expect(click).toHaveBeenCalled();
|
||||
el.getInstance().handleClickImportGrades();
|
||||
expect(mockRef.click).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
describe('handleClickImportGrades', () => {
|
||||
it('does nothing if file input has not loaded with files', () => {
|
||||
fileInput.mockReturnValue(null);
|
||||
el.instance().handleFileInputChange();
|
||||
el.getInstance().handleFileInputChange();
|
||||
expect(props.submitFileUploadFormData).not.toHaveBeenCalled();
|
||||
fileInput.mockReturnValue({ files: [] });
|
||||
el.instance().handleFileInputChange();
|
||||
el.getInstance().handleFileInputChange();
|
||||
expect(props.submitFileUploadFormData).not.toHaveBeenCalled();
|
||||
});
|
||||
it('calls submitFileUploadFormData and then clears fileInput if has files', () => {
|
||||
fileInput.mockReturnValue({ files: ['some', 'files'], value: 'a value' });
|
||||
const formData = { fake: 'form data' };
|
||||
jest.spyOn(el.instance(), 'formData', 'get').mockReturnValue(formData);
|
||||
jest.spyOn(el.getInstance(), 'formData', 'get').mockReturnValue(formData);
|
||||
const submit = jest.fn(() => ({ then: (thenCB) => { thenCB(); } }));
|
||||
el.setProps({
|
||||
submitFileUploadFormData: submit,
|
||||
});
|
||||
el.instance().handleFileInputChange();
|
||||
el.update(<FileUploadForm {...props} submitFileUploadFormData={submit} />);
|
||||
el.getInstance().handleFileInputChange();
|
||||
expect(submit).toHaveBeenCalledWith(formData);
|
||||
expect(el.instance().fileInput.value).toEqual(null);
|
||||
expect(el.getInstance().fileInput.value).toEqual(null);
|
||||
});
|
||||
});
|
||||
describe('formData', () => {
|
||||
@@ -161,7 +187,7 @@ describe('FileUploadForm', () => {
|
||||
fileInput.mockReturnValue({ files: [file], value });
|
||||
const expected = new FormData();
|
||||
expected.append('csv', file);
|
||||
expect([...el.instance().formData.entries()]).toEqual([...expected.entries()]);
|
||||
expect([...el.getInstance().formData.entries()]).toEqual([...expected.entries()]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,11 +3,14 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
import { Table } from '@edx/paragon';
|
||||
|
||||
import { bulkManagementColumns, messages } from 'data/constants/app';
|
||||
import { bulkManagementColumns } from 'data/constants/app';
|
||||
import selectors from 'data/selectors';
|
||||
|
||||
import ResultsSummary from './ResultsSummary';
|
||||
import messages from './messages';
|
||||
|
||||
export const mapHistoryRows = ({
|
||||
resultsSummary,
|
||||
@@ -21,19 +24,19 @@ export const mapHistoryRows = ({
|
||||
...rest,
|
||||
});
|
||||
|
||||
const { hints } = messages.BulkManagementTab;
|
||||
|
||||
/**
|
||||
* <HistoryTable />
|
||||
* Table with history of bulk management uploads, including a results summary which
|
||||
* displays total, skipped, and failed uploads
|
||||
*/
|
||||
export const HistoryTable = ({ bulkManagementHistory }) => (
|
||||
export const HistoryTable = ({
|
||||
bulkManagementHistory,
|
||||
}) => (
|
||||
<>
|
||||
<p>
|
||||
{hints[0]}
|
||||
<FormattedMessage {...messages.hint1} />
|
||||
<br />
|
||||
{hints[1]}
|
||||
<FormattedMessage {...messages.hint2} />
|
||||
</p>
|
||||
|
||||
<Table
|
||||
@@ -55,7 +58,6 @@ HistoryTable.propTypes = {
|
||||
timeUploaded: PropTypes.string.isRequired,
|
||||
resultsSummary: PropTypes.shape({
|
||||
rowId: PropTypes.number.isRequired,
|
||||
courseId: PropTypes.string.isRequired,
|
||||
text: PropTypes.string.isRequired,
|
||||
}),
|
||||
})),
|
||||
|
||||
@@ -2,13 +2,19 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { Table } from '@edx/paragon';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import selectors from 'data/selectors';
|
||||
import { bulkManagementColumns, messages } from 'data/constants/app';
|
||||
import { bulkManagementColumns } from 'data/constants/app';
|
||||
|
||||
import ResultsSummary from './ResultsSummary';
|
||||
import { HistoryTable, mapStateToProps } from './HistoryTable';
|
||||
import messages from './messages';
|
||||
|
||||
jest.mock('@edx/frontend-platform/i18n', () => ({
|
||||
defineMessages: m => m,
|
||||
FormattedMessage: () => 'FormattedMessage',
|
||||
}));
|
||||
jest.mock('@edx/paragon', () => ({
|
||||
Table: () => 'Table',
|
||||
}));
|
||||
@@ -61,9 +67,9 @@ describe('HistoryTable', () => {
|
||||
});
|
||||
test('hints with break in between', () => {
|
||||
const hints = el.find('p');
|
||||
expect(hints.childAt(0).text()).toEqual(messages.BulkManagementTab.hints[0]);
|
||||
expect(hints.childAt(0).getElement()).toEqual(<FormattedMessage {...messages.hint1} />);
|
||||
expect(hints.childAt(1).is('br')).toEqual(true);
|
||||
expect(hints.childAt(2).text()).toEqual(messages.BulkManagementTab.hints[1]);
|
||||
expect(hints.childAt(2).getElement()).toEqual(<FormattedMessage {...messages.hint2} />);
|
||||
});
|
||||
describe('history table', () => {
|
||||
let table;
|
||||
|
||||
@@ -5,7 +5,7 @@ import PropTypes from 'prop-types';
|
||||
import { Hyperlink, Icon } from '@edx/paragon';
|
||||
import { Download } from '@edx/paragon/icons';
|
||||
|
||||
import { bulkGradesUrlByCourseAndRow } from 'data/constants/api';
|
||||
import lms from 'data/services/lms';
|
||||
|
||||
/**
|
||||
* <ResultsSummary {...{ courseId, rowId, text }} />
|
||||
@@ -15,12 +15,11 @@ import { bulkGradesUrlByCourseAndRow } from 'data/constants/api';
|
||||
* @param {string} text - summary string
|
||||
*/
|
||||
const ResultsSummary = ({
|
||||
courseId,
|
||||
rowId,
|
||||
text,
|
||||
}) => (
|
||||
<Hyperlink
|
||||
href={bulkGradesUrlByCourseAndRow(courseId, rowId)}
|
||||
href={lms.urls.bulkGradesUrlByRow(rowId)}
|
||||
destination="www.edx.org"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
@@ -32,7 +31,6 @@ const ResultsSummary = ({
|
||||
);
|
||||
|
||||
ResultsSummary.propTypes = {
|
||||
courseId: PropTypes.string.isRequired,
|
||||
rowId: PropTypes.number.isRequired,
|
||||
text: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@ import { shallow } from 'enzyme';
|
||||
import { Icon } from '@edx/paragon';
|
||||
import { Download } from '@edx/paragon/icons';
|
||||
|
||||
import * as api from 'data/constants/api';
|
||||
import lms from 'data/services/lms';
|
||||
import ResultsSummary from './ResultsSummary';
|
||||
|
||||
jest.mock('@edx/paragon', () => ({
|
||||
@@ -14,13 +14,14 @@ jest.mock('@edx/paragon', () => ({
|
||||
jest.mock('@edx/paragon/icons', () => ({
|
||||
Download: 'DownloadIcon',
|
||||
}));
|
||||
jest.mock('data/constants/api', () => ({
|
||||
bulkGradesUrlByCourseAndRow: jest.fn((courseId, rowId) => ({ url: { courseId, rowId } })),
|
||||
jest.mock('data/services/lms', () => ({
|
||||
urls: {
|
||||
bulkGradesUrlByRow: jest.fn((rowId) => ({ url: { rowId } })),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('ResultsSummary component', () => {
|
||||
const props = {
|
||||
courseId: 'classy',
|
||||
rowId: 42,
|
||||
text: 'texty',
|
||||
};
|
||||
@@ -41,7 +42,7 @@ describe('ResultsSummary component', () => {
|
||||
expect(el.props().rel).toEqual('noopener noreferrer');
|
||||
});
|
||||
test('Hyperlink has href to bulkGradesUrl', () => {
|
||||
expect(el.props().href).toEqual(api.bulkGradesUrlByCourseAndRow(props.courseId, props.rowId));
|
||||
expect(el.props().href).toEqual(lms.urls.bulkGradesUrlByRow(props.rowId));
|
||||
});
|
||||
test('displays Download Icon and text', () => {
|
||||
const icon = el.childAt(0);
|
||||
|
||||
@@ -12,7 +12,11 @@ exports[`BulkManagementAlerts component no errer, no upload success snapshot - b
|
||||
show={false}
|
||||
variant="success"
|
||||
>
|
||||
CSV processing. File uploads may take several minutes to complete.
|
||||
<FormattedMessage
|
||||
defaultMessage="CSV processing. File uploads may take several minutes to complete."
|
||||
description="Success Dialog message in BulkManagement Tab File Upload Form"
|
||||
id="gradebook.BulkManagementTab.successDialog"
|
||||
/>
|
||||
</Alert>
|
||||
</Fragment>
|
||||
`;
|
||||
@@ -31,7 +35,11 @@ exports[`BulkManagementAlerts component no errer, no upload success snapshot - d
|
||||
show={true}
|
||||
variant="success"
|
||||
>
|
||||
CSV processing. File uploads may take several minutes to complete.
|
||||
<FormattedMessage
|
||||
defaultMessage="CSV processing. File uploads may take several minutes to complete."
|
||||
description="Success Dialog message in BulkManagement Tab File Upload Form"
|
||||
id="gradebook.BulkManagementTab.successDialog"
|
||||
/>
|
||||
</Alert>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
@@ -16,7 +16,13 @@ exports[`FileUploadForm component snapshot snapshot - loads export form w/ alert
|
||||
<ForwardRef
|
||||
as="input"
|
||||
className="d-none"
|
||||
label="Upload Grade CSV"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Upload Grade CSV"
|
||||
description="Button in BulkManagementTab Alerts"
|
||||
id="gradebook.BulkManagementTab.csvUploadLabel"
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction this.handleFileInputChange]}
|
||||
plaintext={false}
|
||||
type="file"
|
||||
@@ -29,7 +35,11 @@ exports[`FileUploadForm component snapshot snapshot - loads export form w/ alert
|
||||
onClick={[MockFunction this.handleClickImportGrades]}
|
||||
variant="primary"
|
||||
>
|
||||
Import Grades
|
||||
<FormattedMessage
|
||||
defaultMessage="Import Grades"
|
||||
description="Button in BulkManagement Tab File Upload Form"
|
||||
id="gradebook.BulkManagementTab.importBtnText"
|
||||
/>
|
||||
</ForwardRef>
|
||||
</React.Fragment>
|
||||
`;
|
||||
|
||||
@@ -44,9 +44,17 @@ Array [
|
||||
exports[`HistoryTable component snapshot snapshot - loads hints display, formatted table 1`] = `
|
||||
<Fragment>
|
||||
<p>
|
||||
Results appear in the table below.
|
||||
<FormattedMessage
|
||||
defaultMessage="Results appear in the table below."
|
||||
description="Hint text on BulkManagement Tab History Table"
|
||||
id="gradebook.BulkManagementTab.hint1"
|
||||
/>
|
||||
<br />
|
||||
Grade processing may take a few seconds.
|
||||
<FormattedMessage
|
||||
defaultMessage="Grade processing may take a few seconds."
|
||||
description="Hint text on BulkManagement Tab History Table"
|
||||
id="gradebook.BulkManagementTab.hint2"
|
||||
/>
|
||||
</p>
|
||||
<Table
|
||||
className="table-striped"
|
||||
|
||||
@@ -6,7 +6,6 @@ exports[`ResultsSummary component snapshot - safe hyperlink with bulkGradesUrl w
|
||||
href={
|
||||
Object {
|
||||
"url": Object {
|
||||
"courseId": "classy",
|
||||
"rowId": 42,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
exports[`BulkManagementTab component snapshot snapshot - loads heading from messages.BulkManagementTab.heading, <BulkManagementAlerts />, <FileUploadForm />, <HistoryTable /> 1`] = `
|
||||
<div>
|
||||
<h4>
|
||||
Use this feature by downloading a CSV for bulk management, overriding grades locally, and coming back here to upload.
|
||||
<FormattedMessage
|
||||
defaultMessage="Use this feature by downloading a CSV for bulk management, overriding grades locally, and coming back here to upload."
|
||||
description="Heading text for BulkManagement Tab"
|
||||
id="gradebook.BulkManagementTab.heading"
|
||||
/>
|
||||
</h4>
|
||||
<BulkManagementAlerts />
|
||||
<FileUploadForm />
|
||||
@@ -1,7 +1,8 @@
|
||||
/* eslint-disable react/button-has-type, import/no-named-as-default */
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { messages } from 'data/constants/app';
|
||||
import messages from './messages';
|
||||
import BulkManagementAlerts from './BulkManagementAlerts';
|
||||
import FileUploadForm from './FileUploadForm';
|
||||
import HistoryTable from './HistoryTable';
|
||||
@@ -12,7 +13,7 @@ import HistoryTable from './HistoryTable';
|
||||
*/
|
||||
export const BulkManagementTab = () => (
|
||||
<div>
|
||||
<h4>{messages.BulkManagementTab.heading}</h4>
|
||||
<h4><FormattedMessage {...(messages.heading)} /></h4>
|
||||
<BulkManagementAlerts />
|
||||
<FileUploadForm />
|
||||
<HistoryTable />
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
/* eslint-disable import/no-named-as-default */
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { messages } from 'data/constants/app';
|
||||
import { BulkManagementTab } from '.';
|
||||
import BulkManagementAlerts from './BulkManagementAlerts';
|
||||
import FileUploadForm from './FileUploadForm';
|
||||
import HistoryTable from './HistoryTable';
|
||||
import messages from './messages';
|
||||
|
||||
jest.mock('./BulkManagementAlerts', () => 'BulkManagementAlerts');
|
||||
jest.mock('./FileUploadForm', () => 'FileUploadForm');
|
||||
@@ -30,7 +31,11 @@ describe('BulkManagementTab', () => {
|
||||
});
|
||||
test('heading - h4 loaded from messages', () => {
|
||||
const heading = el.find('h4');
|
||||
expect(heading.text()).toEqual(messages.BulkManagementTab.heading);
|
||||
expect(heading.getElement()).toEqual((
|
||||
<h4>
|
||||
<FormattedMessage {...messages.heading} />
|
||||
</h4>
|
||||
));
|
||||
});
|
||||
test('heading, then alerts, then upload form, then table', () => {
|
||||
expect(el.childAt(0).is('h4')).toEqual(true);
|
||||
36
src/components/BulkManagementTab/messages.js
Normal file
36
src/components/BulkManagementTab/messages.js
Normal file
@@ -0,0 +1,36 @@
|
||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||
|
||||
const messages = defineMessages({
|
||||
csvUploadLabel: {
|
||||
id: 'gradebook.BulkManagementTab.csvUploadLabel',
|
||||
defaultMessage: 'Upload Grade CSV',
|
||||
description: 'Button in BulkManagementTab Alerts',
|
||||
},
|
||||
heading: {
|
||||
id: 'gradebook.BulkManagementTab.heading',
|
||||
defaultMessage: 'Use this feature by downloading a CSV for bulk management, overriding grades locally, and coming back here to upload.',
|
||||
description: 'Heading text for BulkManagement Tab',
|
||||
},
|
||||
hint1: {
|
||||
id: 'gradebook.BulkManagementTab.hint1',
|
||||
defaultMessage: 'Results appear in the table below.',
|
||||
description: 'Hint text on BulkManagement Tab History Table',
|
||||
},
|
||||
hint2: {
|
||||
id: 'gradebook.BulkManagementTab.hint2',
|
||||
defaultMessage: 'Grade processing may take a few seconds.',
|
||||
description: 'Hint text on BulkManagement Tab History Table',
|
||||
},
|
||||
importBtnText: {
|
||||
id: 'gradebook.BulkManagementTab.importBtnText',
|
||||
defaultMessage: 'Import Grades',
|
||||
description: 'Button in BulkManagement Tab File Upload Form',
|
||||
},
|
||||
successDialog: {
|
||||
id: 'gradebook.BulkManagementTab.successDialog',
|
||||
defaultMessage: 'CSV processing. File uploads may take several minutes to complete.',
|
||||
description: 'Success Dialog message in BulkManagement Tab File Upload Form',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -7,7 +7,13 @@ exports[`AssignmentFilter Component snapshots basic snapshot 1`] = `
|
||||
<SelectGroup
|
||||
disabled={false}
|
||||
id="assignment"
|
||||
label="Assignment"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Assignment"
|
||||
description="Assignment filter select label in Gradebook Filters"
|
||||
id="gradebook.GradebookFilters.assignmentFilterLabel"
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction handleChange]}
|
||||
options={
|
||||
Array [
|
||||
|
||||
@@ -3,10 +3,13 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import selectors from 'data/selectors';
|
||||
import actions from 'data/actions';
|
||||
import thunkActions from 'data/thunkActions';
|
||||
|
||||
import messages from '../messages';
|
||||
import SelectGroup from '../SelectGroup';
|
||||
|
||||
const { fetchGradesIfAssignmentGradeFiltersSet } = thunkActions.grades;
|
||||
@@ -46,7 +49,7 @@ export class AssignmentFilter extends React.Component {
|
||||
<div className="student-filters">
|
||||
<SelectGroup
|
||||
id="assignment"
|
||||
label="Assignment"
|
||||
label={<FormattedMessage {...messages.assignment} />}
|
||||
value={this.props.selectedAssignment}
|
||||
onChange={this.handleChange}
|
||||
disabled={this.props.assignmentFilterOptions.length === 0}
|
||||
@@ -64,7 +67,6 @@ AssignmentFilter.defaultProps = {
|
||||
|
||||
AssignmentFilter.propTypes = {
|
||||
updateQueryParams: PropTypes.func.isRequired,
|
||||
|
||||
// redux
|
||||
assignmentFilterOptions: PropTypes.arrayOf(PropTypes.shape({
|
||||
label: PropTypes.string,
|
||||
|
||||
@@ -69,7 +69,6 @@ describe('AssignmentFilter', () => {
|
||||
el = mount(<AssignmentFilter {...props} />);
|
||||
el.instance().handleChange(event);
|
||||
});
|
||||
|
||||
it('calls props.updateAssignmentFilter with selection', () => {
|
||||
expect(props.updateAssignmentFilter).toHaveBeenCalledWith({
|
||||
label: newAssgn,
|
||||
@@ -87,6 +86,30 @@ describe('AssignmentFilter', () => {
|
||||
const method = props.fetchGradesIfAssignmentGradeFiltersSet;
|
||||
expect(method).toHaveBeenCalledWith();
|
||||
});
|
||||
describe('no selected option', () => {
|
||||
const value = 'fake';
|
||||
beforeEach(() => {
|
||||
el = mount(<AssignmentFilter {...props} />);
|
||||
el.instance().handleChange({ target: { value } });
|
||||
});
|
||||
it('calls props.updateAssignmentFilter with selection', () => {
|
||||
expect(props.updateAssignmentFilter).toHaveBeenCalledWith({
|
||||
label: value,
|
||||
type: undefined,
|
||||
id: undefined,
|
||||
});
|
||||
});
|
||||
it('calls props.updateQueryParams with selected assignment id',
|
||||
() => {
|
||||
expect(props.updateQueryParams).toHaveBeenCalledWith({
|
||||
assignment: undefined,
|
||||
});
|
||||
});
|
||||
it('calls props.fetchGradesIfAssignmentGradeFiltersSet', () => {
|
||||
const method = props.fetchGradesIfAssignmentGradeFiltersSet;
|
||||
expect(method).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('snapshots', () => {
|
||||
|
||||
@@ -7,14 +7,26 @@ exports[`AssignmentGradeFilter Component snapshots buttons and groups disabled i
|
||||
<PercentGroup
|
||||
disabled={true}
|
||||
id="assignmentGradeMin"
|
||||
label="Min Grade"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Min Grade"
|
||||
description="Min-grade filter select label in Gradebook Filters"
|
||||
id="gradebook.GradebookFilters.minGradeFilterLabel"
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction handleSetMin]}
|
||||
value="2"
|
||||
/>
|
||||
<PercentGroup
|
||||
disabled={true}
|
||||
id="assignmentGradeMax"
|
||||
label="Max Grade"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Max Grade"
|
||||
description="Max-grade filter select label in Gradebook Filters"
|
||||
id="gradebook.GradebookFilters.maxGradeFilterLabel"
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction handleSetMax]}
|
||||
value="98"
|
||||
/>
|
||||
@@ -42,14 +54,26 @@ exports[`AssignmentGradeFilter Component snapshots smoke test 1`] = `
|
||||
<PercentGroup
|
||||
disabled={false}
|
||||
id="assignmentGradeMin"
|
||||
label="Min Grade"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Min Grade"
|
||||
description="Min-grade filter select label in Gradebook Filters"
|
||||
id="gradebook.GradebookFilters.minGradeFilterLabel"
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction handleSetMin]}
|
||||
value="2"
|
||||
/>
|
||||
<PercentGroup
|
||||
disabled={false}
|
||||
id="assignmentGradeMax"
|
||||
label="Max Grade"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Max Grade"
|
||||
description="Max-grade filter select label in Gradebook Filters"
|
||||
id="gradebook.GradebookFilters.maxGradeFilterLabel"
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction handleSetMax]}
|
||||
value="98"
|
||||
/>
|
||||
|
||||
@@ -3,12 +3,14 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
import { Button } from '@edx/paragon';
|
||||
|
||||
import selectors from 'data/selectors';
|
||||
import actions from 'data/actions';
|
||||
import thunkActions from 'data/thunkActions';
|
||||
|
||||
import messages from '../messages';
|
||||
import PercentGroup from '../PercentGroup';
|
||||
|
||||
export class AssignmentGradeFilter extends React.Component {
|
||||
@@ -34,19 +36,21 @@ export class AssignmentGradeFilter extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { assignmentGradeMin, assignmentGradeMax } = this.props.localAssignmentLimits;
|
||||
const {
|
||||
localAssignmentLimits: { assignmentGradeMax, assignmentGradeMin },
|
||||
} = this.props;
|
||||
return (
|
||||
<div className="grade-filter-inputs">
|
||||
<PercentGroup
|
||||
id="assignmentGradeMin"
|
||||
label="Min Grade"
|
||||
label={<FormattedMessage {...messages.minGrade} />}
|
||||
value={assignmentGradeMin}
|
||||
disabled={!this.props.selectedAssignment}
|
||||
onChange={this.handleSetMin}
|
||||
/>
|
||||
<PercentGroup
|
||||
id="assignmentGradeMax"
|
||||
label="Max Grade"
|
||||
label={<FormattedMessage {...messages.maxGrade} />}
|
||||
value={assignmentGradeMax}
|
||||
disabled={!this.props.selectedAssignment}
|
||||
onChange={this.handleSetMax}
|
||||
|
||||
@@ -7,7 +7,13 @@ exports[`AssignmentTypeFilter Component snapshots SelectGroup disabled if no ass
|
||||
<SelectGroup
|
||||
disabled={true}
|
||||
id="assignment-types"
|
||||
label="Assignment Types"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Assignment Types"
|
||||
description="Assignment Types filter select label in Gradebook Filters"
|
||||
id="gradebook.GradebookFilters.assignmentTypesLabel"
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction handleChange]}
|
||||
options={
|
||||
Array [
|
||||
@@ -40,7 +46,13 @@ exports[`AssignmentTypeFilter Component snapshots smoke test 1`] = `
|
||||
<SelectGroup
|
||||
disabled={false}
|
||||
id="assignment-types"
|
||||
label="Assignment Types"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Assignment Types"
|
||||
description="Assignment Types filter select label in Gradebook Filters"
|
||||
id="gradebook.GradebookFilters.assignmentTypesLabel"
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction handleChange]}
|
||||
options={
|
||||
Array [
|
||||
|
||||
@@ -3,9 +3,13 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import selectors from 'data/selectors';
|
||||
import actions from 'data/actions';
|
||||
|
||||
import SelectGroup from '../SelectGroup';
|
||||
import messages from '../messages';
|
||||
|
||||
export class AssignmentTypeFilter extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -34,7 +38,7 @@ export class AssignmentTypeFilter extends React.Component {
|
||||
<div className="student-filters">
|
||||
<SelectGroup
|
||||
id="assignment-types"
|
||||
label="Assignment Types"
|
||||
label={<FormattedMessage {...messages.assignmentTypes} />}
|
||||
value={this.props.selectedAssignmentType}
|
||||
onChange={this.handleChange}
|
||||
disabled={this.props.assignmentFilterOptions.length === 0}
|
||||
|
||||
@@ -7,13 +7,25 @@ exports[`CourseGradeFilter Component snapshots basic snapshot 1`] = `
|
||||
>
|
||||
<PercentGroup
|
||||
id="minimum-grade"
|
||||
label="Min Grade"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Min Grade"
|
||||
description="Min-grade filter select label in Gradebook Filters"
|
||||
id="gradebook.GradebookFilters.minGradeFilterLabel"
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction handleUpdateMin]}
|
||||
value="5"
|
||||
/>
|
||||
<PercentGroup
|
||||
id="maximum-grade"
|
||||
label="Max Grade"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Max Grade"
|
||||
description="Max-grade filter select label in Gradebook Filters"
|
||||
id="gradebook.GradebookFilters.maxGradeFilterLabel"
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction handleUpdateMax]}
|
||||
value="92"
|
||||
/>
|
||||
|
||||
@@ -2,13 +2,15 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Button,
|
||||
} from '@edx/paragon';
|
||||
|
||||
import { Button } from '@edx/paragon';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import selectors from 'data/selectors';
|
||||
import actions from 'data/actions';
|
||||
import thunkActions from 'data/thunkActions';
|
||||
|
||||
import messages from '../messages';
|
||||
import PercentGroup from '../PercentGroup';
|
||||
|
||||
export class CourseGradeFilter extends React.Component {
|
||||
@@ -41,19 +43,21 @@ export class CourseGradeFilter extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { courseGradeMin, courseGradeMax } = this.props.localCourseLimits;
|
||||
const {
|
||||
localCourseLimits: { courseGradeMin, courseGradeMax },
|
||||
} = this.props;
|
||||
return (
|
||||
<>
|
||||
<div className="grade-filter-inputs">
|
||||
<PercentGroup
|
||||
id="minimum-grade"
|
||||
label="Min Grade"
|
||||
label={<FormattedMessage {...messages.minGrade} />}
|
||||
value={courseGradeMin}
|
||||
onChange={this.handleUpdateMin}
|
||||
/>
|
||||
<PercentGroup
|
||||
id="maximum-grade"
|
||||
label="Max Grade"
|
||||
label={<FormattedMessage {...messages.maxGrade} />}
|
||||
value={courseGradeMax}
|
||||
onChange={this.handleUpdateMax}
|
||||
/>
|
||||
|
||||
@@ -30,7 +30,7 @@ PercentGroup.defaultProps = {
|
||||
};
|
||||
PercentGroup.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
label: PropTypes.string.isRequired,
|
||||
label: PropTypes.node.isRequired,
|
||||
value: PropTypes.string.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
disabled: PropTypes.bool,
|
||||
|
||||
@@ -23,7 +23,7 @@ const SelectGroup = ({
|
||||
);
|
||||
SelectGroup.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
label: PropTypes.string.isRequired,
|
||||
label: PropTypes.node.isRequired,
|
||||
value: PropTypes.string.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
disabled: PropTypes.bool,
|
||||
|
||||
@@ -3,10 +3,13 @@ import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import actions from 'data/actions';
|
||||
import selectors from 'data/selectors';
|
||||
import thunkActions from 'data/thunkActions';
|
||||
|
||||
import messages from '../messages';
|
||||
import SelectGroup from '../SelectGroup';
|
||||
|
||||
export const optionFactory = ({ data, defaultOption, key }) => [
|
||||
@@ -28,7 +31,7 @@ export class StudentGroupsFilter extends React.Component {
|
||||
mapCohortsEntries() {
|
||||
return optionFactory({
|
||||
data: this.props.cohorts,
|
||||
defaultOption: 'Cohort-All',
|
||||
defaultOption: this.translate(messages.cohortAll),
|
||||
key: 'id',
|
||||
});
|
||||
}
|
||||
@@ -36,7 +39,7 @@ export class StudentGroupsFilter extends React.Component {
|
||||
mapTracksEntries() {
|
||||
return optionFactory({
|
||||
data: this.props.tracks,
|
||||
defaultOption: 'Track-All',
|
||||
defaultOption: this.translate(messages.trackAll),
|
||||
key: 'slug',
|
||||
});
|
||||
}
|
||||
@@ -65,19 +68,23 @@ export class StudentGroupsFilter extends React.Component {
|
||||
this.props.fetchGrades();
|
||||
}
|
||||
|
||||
translate(message) {
|
||||
return this.props.intl.formatMessage(message);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
<SelectGroup
|
||||
id="Tracks"
|
||||
label="Tracks"
|
||||
label={this.translate(messages.tracks)}
|
||||
value={this.props.selectedTrackEntry.name}
|
||||
onChange={this.updateTracks}
|
||||
options={this.mapTracksEntries()}
|
||||
/>
|
||||
<SelectGroup
|
||||
id="Cohorts"
|
||||
label="Cohorts"
|
||||
label={this.translate(messages.cohorts)}
|
||||
value={this.props.selectedCohortEntry.name}
|
||||
disabled={this.props.cohorts.length === 0}
|
||||
onChange={this.updateCohorts}
|
||||
@@ -100,6 +107,9 @@ StudentGroupsFilter.defaultProps = {
|
||||
StudentGroupsFilter.propTypes = {
|
||||
updateQueryParams: PropTypes.func.isRequired,
|
||||
|
||||
// injected
|
||||
intl: intlShape.isRequired,
|
||||
|
||||
// redux
|
||||
cohorts: PropTypes.arrayOf(PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
@@ -139,4 +149,4 @@ export const mapDispatchToProps = {
|
||||
updateTrack: actions.filters.update.track,
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(StudentGroupsFilter);
|
||||
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(StudentGroupsFilter));
|
||||
|
||||
@@ -63,6 +63,7 @@ describe('StudentGroupsFilter', () => {
|
||||
beforeEach(() => {
|
||||
props = {
|
||||
...props,
|
||||
intl: { formatMessage: (msg) => msg.defaultMessage },
|
||||
cohortsByName: {
|
||||
[props.cohorts[0].name]: props.cohorts[0],
|
||||
[props.cohorts[1].name]: props.cohorts[1],
|
||||
|
||||
@@ -22,7 +22,13 @@ exports[`GradebookFilters Component snapshots basic snapshot 1`] = `
|
||||
<Collapsible
|
||||
className="filter-group mb-3"
|
||||
defaultOpen={true}
|
||||
title="Assignments"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Assignments"
|
||||
description="Assignment filter group label in Gradebook Filters"
|
||||
id="gradebook.GradebookFilters.assignmentsFilterLabel"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<div>
|
||||
<Connect(AssignmentTypeFilter)
|
||||
@@ -39,7 +45,13 @@ exports[`GradebookFilters Component snapshots basic snapshot 1`] = `
|
||||
<Collapsible
|
||||
className="filter-group mb-3"
|
||||
defaultOpen={true}
|
||||
title="Overall Grade"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Overall Grade"
|
||||
description="Overall Grade filter group label in Gradebook Filters"
|
||||
id="gradebook.GradebookFilters.overallGradeFilterLabel"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Connect(CourseGradeFilter)
|
||||
updateQueryParams={[MockFunction]}
|
||||
@@ -48,22 +60,38 @@ exports[`GradebookFilters Component snapshots basic snapshot 1`] = `
|
||||
<Collapsible
|
||||
className="filter-group mb-3"
|
||||
defaultOpen={true}
|
||||
title="Student Groups"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Student Groups"
|
||||
description="Student Groups filter group label in Gradebook Filters"
|
||||
id="gradebook.GradebookFilters.studentGroupsFilterLabel"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Connect(StudentGroupsFilter)
|
||||
<InjectIntl(ShimmedIntlComponent)
|
||||
updateQueryParams={[MockFunction]}
|
||||
/>
|
||||
</Collapsible>
|
||||
<Collapsible
|
||||
className="filter-group mb-3"
|
||||
defaultOpen={true}
|
||||
title="Include Course Team Members"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Include Course Team Members"
|
||||
description="Include Course Team Members filter label in Gradebook Filters"
|
||||
id="gradebook.GradebookFilters.includeCourseTeamMembersFilterLabel"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Checkbox
|
||||
checked={true}
|
||||
onChange={[MockFunction handleIncludeTeamMembersChange]}
|
||||
>
|
||||
Include Course Team Members
|
||||
<FormattedMessage
|
||||
defaultMessage="Include Course Team Members"
|
||||
description="Include Course Team Members filter label in Gradebook Filters"
|
||||
id="gradebook.GradebookFilters.includeCourseTeamMembersFilterLabel"
|
||||
/>
|
||||
</Checkbox>
|
||||
</Collapsible>
|
||||
</React.Fragment>
|
||||
|
||||
@@ -10,11 +10,13 @@ import {
|
||||
Form,
|
||||
} from '@edx/paragon';
|
||||
import { Close } from '@edx/paragon/icons';
|
||||
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import actions from 'data/actions';
|
||||
import selectors from 'data/selectors';
|
||||
import thunkActions from 'data/thunkActions';
|
||||
|
||||
import messages from './messages';
|
||||
import AssignmentTypeFilter from './AssignmentTypeFilter';
|
||||
import AssignmentFilter from './AssignmentFilter';
|
||||
import AssignmentGradeFilter from './AssignmentGradeFilter';
|
||||
@@ -39,13 +41,18 @@ export class GradebookFilters extends React.Component {
|
||||
}
|
||||
|
||||
collapsibleGroup = (title, content) => (
|
||||
<Collapsible title={title} defaultOpen className="filter-group mb-3">
|
||||
<Collapsible
|
||||
title={<FormattedMessage {...title} />}
|
||||
defaultOpen
|
||||
className="filter-group mb-3"
|
||||
>
|
||||
{content}
|
||||
</Collapsible>
|
||||
);
|
||||
|
||||
render() {
|
||||
const {
|
||||
intl,
|
||||
updateQueryParams,
|
||||
} = this.props;
|
||||
return (
|
||||
@@ -57,12 +64,12 @@ export class GradebookFilters extends React.Component {
|
||||
onClick={this.props.closeMenu}
|
||||
iconAs={Icon}
|
||||
src={Close}
|
||||
alt="Close Filters"
|
||||
aria-label="Close Filters"
|
||||
alt={intl.formatMessage(messages.closeFilters)}
|
||||
aria-label={intl.formatMessage(messages.closeFilters)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{this.collapsibleGroup('Assignments', (
|
||||
{this.collapsibleGroup(messages.assignments, (
|
||||
<div>
|
||||
<AssignmentTypeFilter updateQueryParams={updateQueryParams} />
|
||||
<AssignmentFilter updateQueryParams={updateQueryParams} />
|
||||
@@ -70,20 +77,20 @@ export class GradebookFilters extends React.Component {
|
||||
</div>
|
||||
))}
|
||||
|
||||
{this.collapsibleGroup('Overall Grade', (
|
||||
{this.collapsibleGroup(messages.overallGrade, (
|
||||
<CourseGradeFilter updateQueryParams={updateQueryParams} />
|
||||
))}
|
||||
|
||||
{this.collapsibleGroup('Student Groups', (
|
||||
{this.collapsibleGroup(messages.studentGroups, (
|
||||
<StudentGroupsFilter updateQueryParams={updateQueryParams} />
|
||||
))}
|
||||
|
||||
{this.collapsibleGroup('Include Course Team Members', (
|
||||
{this.collapsibleGroup(messages.includeCourseTeamMembers, (
|
||||
<Form.Checkbox
|
||||
checked={this.state.includeCourseRoleMembers}
|
||||
onChange={this.handleIncludeTeamMembersChange}
|
||||
>
|
||||
Include Course Team Members
|
||||
<FormattedMessage {...messages.includeCourseTeamMembers} />
|
||||
</Form.Checkbox>
|
||||
))}
|
||||
</>
|
||||
@@ -95,6 +102,8 @@ GradebookFilters.defaultProps = {
|
||||
};
|
||||
GradebookFilters.propTypes = {
|
||||
updateQueryParams: PropTypes.func.isRequired,
|
||||
// injected
|
||||
intl: intlShape.isRequired,
|
||||
// redux
|
||||
closeMenu: PropTypes.func.isRequired,
|
||||
fetchGrades: PropTypes.func.isRequired,
|
||||
@@ -112,4 +121,4 @@ export const mapDispatchToProps = {
|
||||
updateIncludeCourseRoleMembers: actions.filters.update.includeCourseRoleMembers,
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(GradebookFilters);
|
||||
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(GradebookFilters));
|
||||
|
||||
71
src/components/GradebookFilters/messages.js
Normal file
71
src/components/GradebookFilters/messages.js
Normal file
@@ -0,0 +1,71 @@
|
||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||
|
||||
const messages = defineMessages({
|
||||
assignments: {
|
||||
id: 'gradebook.GradebookFilters.assignmentsFilterLabel',
|
||||
defaultMessage: 'Assignments',
|
||||
description: 'Assignment filter group label in Gradebook Filters',
|
||||
},
|
||||
overallGrade: {
|
||||
id: 'gradebook.GradebookFilters.overallGradeFilterLabel',
|
||||
defaultMessage: 'Overall Grade',
|
||||
description: 'Overall Grade filter group label in Gradebook Filters',
|
||||
},
|
||||
studentGroups: {
|
||||
id: 'gradebook.GradebookFilters.studentGroupsFilterLabel',
|
||||
defaultMessage: 'Student Groups',
|
||||
description: 'Student Groups filter group label in Gradebook Filters',
|
||||
},
|
||||
includeCourseTeamMembers: {
|
||||
id: 'gradebook.GradebookFilters.includeCourseTeamMembersFilterLabel',
|
||||
defaultMessage: 'Include Course Team Members',
|
||||
description: 'Include Course Team Members filter label in Gradebook Filters',
|
||||
},
|
||||
assignment: {
|
||||
id: 'gradebook.GradebookFilters.assignmentFilterLabel',
|
||||
defaultMessage: 'Assignment',
|
||||
description: 'Assignment filter select label in Gradebook Filters',
|
||||
},
|
||||
assignmentTypes: {
|
||||
id: 'gradebook.GradebookFilters.assignmentTypesLabel',
|
||||
defaultMessage: 'Assignment Types',
|
||||
description: 'Assignment Types filter select label in Gradebook Filters',
|
||||
},
|
||||
maxGrade: {
|
||||
id: 'gradebook.GradebookFilters.maxGradeFilterLabel',
|
||||
defaultMessage: 'Max Grade',
|
||||
description: 'Max-grade filter select label in Gradebook Filters',
|
||||
},
|
||||
minGrade: {
|
||||
id: 'gradebook.GradebookFilters.minGradeFilterLabel',
|
||||
defaultMessage: 'Min Grade',
|
||||
description: 'Min-grade filter select label in Gradebook Filters',
|
||||
},
|
||||
cohorts: {
|
||||
id: 'gradebook.GradebookFilters.cohorts',
|
||||
defaultMessage: 'Cohorts',
|
||||
description: 'Cohorts filter select label in Gradebook Filters',
|
||||
},
|
||||
cohortAll: {
|
||||
id: 'gradebook.GradebookFilters.cohortsAll',
|
||||
defaultMessage: 'Cohort-All',
|
||||
description: 'Cohorts filter select default in Gradebook Filters',
|
||||
},
|
||||
tracks: {
|
||||
id: 'gradebook.GradebookFilters.tracks',
|
||||
defaultMessage: 'Tracks',
|
||||
description: 'Tracks filter select label in Gradebook Filters',
|
||||
},
|
||||
trackAll: {
|
||||
id: 'gradebook.GradebookFilters.trackAll',
|
||||
defaultMessage: 'Track-All',
|
||||
description: 'Tracks filter select default in Gradebook Filters',
|
||||
},
|
||||
closeFilters: {
|
||||
id: 'gradebook.GradebookFilters.closeFilters',
|
||||
defaultMessage: 'Close Filters',
|
||||
description: 'Button label for Close button in Gradebook Filters',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -46,6 +46,7 @@ describe('GradebookFilters', () => {
|
||||
beforeEach(() => {
|
||||
props = {
|
||||
...props,
|
||||
intl: { formatMessage: (msg) => msg.defaultMessage },
|
||||
closeMenu: jest.fn().mockName('this.props.closeMenu'),
|
||||
fetchGrades: jest.fn(),
|
||||
updateIncludeCourseRoleMembers: jest.fn(),
|
||||
|
||||
@@ -13,20 +13,31 @@ exports[`GradebookHeader component snapshots default values (grades frozen, cann
|
||||
>
|
||||
<<
|
||||
</span>
|
||||
Back to Dashboard
|
||||
<FormattedMessage
|
||||
defaultMessage="Back to Dashboard"
|
||||
description="Button text to take user back to LMS dashboard in Gradebook Header"
|
||||
id="gradebook.GradebookHeader.backButton"
|
||||
/>
|
||||
</a>
|
||||
<h1>
|
||||
Gradebook
|
||||
<FormattedMessage
|
||||
defaultMessage="Gradebook"
|
||||
description="Top-level app title in Gradebook Header component"
|
||||
id="gradebook.GradebookHeader.appLabel"
|
||||
/>
|
||||
</h1>
|
||||
<h3>
|
||||
|
||||
fakeID
|
||||
</h3>
|
||||
<div
|
||||
className="alert alert-warning"
|
||||
role="alert"
|
||||
>
|
||||
You are not authorized to view the gradebook for this course.
|
||||
<FormattedMessage
|
||||
defaultMessage="You are not authorized to view the gradebook for this course."
|
||||
description="Warning message in Gradebook Header when user is not allowed to view the app"
|
||||
id="gradebook.GradebookHeader.unauthorizedWarning"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -44,20 +55,31 @@ exports[`GradebookHeader component snapshots grades frozen, can view. grades fro
|
||||
>
|
||||
<<
|
||||
</span>
|
||||
Back to Dashboard
|
||||
<FormattedMessage
|
||||
defaultMessage="Back to Dashboard"
|
||||
description="Button text to take user back to LMS dashboard in Gradebook Header"
|
||||
id="gradebook.GradebookHeader.backButton"
|
||||
/>
|
||||
</a>
|
||||
<h1>
|
||||
Gradebook
|
||||
<FormattedMessage
|
||||
defaultMessage="Gradebook"
|
||||
description="Top-level app title in Gradebook Header component"
|
||||
id="gradebook.GradebookHeader.appLabel"
|
||||
/>
|
||||
</h1>
|
||||
<h3>
|
||||
|
||||
fakeID
|
||||
</h3>
|
||||
<div
|
||||
className="alert alert-warning"
|
||||
role="alert"
|
||||
>
|
||||
The grades for this course are now frozen. Editing of grades is no longer allowed.
|
||||
<FormattedMessage
|
||||
defaultMessage="The grades for this course are now frozen. Editing of grades is no longer allowed."
|
||||
description="Warning message in Gradebook Header for frozen messages"
|
||||
id="gradebook.GradebookHeader.frozenWarning"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -75,26 +97,41 @@ exports[`GradebookHeader component snapshots grades frozen, cannot view unauthor
|
||||
>
|
||||
<<
|
||||
</span>
|
||||
Back to Dashboard
|
||||
<FormattedMessage
|
||||
defaultMessage="Back to Dashboard"
|
||||
description="Button text to take user back to LMS dashboard in Gradebook Header"
|
||||
id="gradebook.GradebookHeader.backButton"
|
||||
/>
|
||||
</a>
|
||||
<h1>
|
||||
Gradebook
|
||||
<FormattedMessage
|
||||
defaultMessage="Gradebook"
|
||||
description="Top-level app title in Gradebook Header component"
|
||||
id="gradebook.GradebookHeader.appLabel"
|
||||
/>
|
||||
</h1>
|
||||
<h3>
|
||||
|
||||
fakeID
|
||||
</h3>
|
||||
<div
|
||||
className="alert alert-warning"
|
||||
role="alert"
|
||||
>
|
||||
The grades for this course are now frozen. Editing of grades is no longer allowed.
|
||||
<FormattedMessage
|
||||
defaultMessage="The grades for this course are now frozen. Editing of grades is no longer allowed."
|
||||
description="Warning message in Gradebook Header for frozen messages"
|
||||
id="gradebook.GradebookHeader.frozenWarning"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="alert alert-warning"
|
||||
role="alert"
|
||||
>
|
||||
You are not authorized to view the gradebook for this course.
|
||||
<FormattedMessage
|
||||
defaultMessage="You are not authorized to view the gradebook for this course."
|
||||
description="Warning message in Gradebook Header when user is not allowed to view the app"
|
||||
id="gradebook.GradebookHeader.unauthorizedWarning"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -2,9 +2,13 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { configuration } from 'config';
|
||||
import selectors from 'data/selectors';
|
||||
|
||||
import messages from './messages';
|
||||
|
||||
export class GradebookHeader extends React.Component {
|
||||
lmsInstructorDashboardUrl = courseId => (
|
||||
`${configuration.LMS_BASE_URL}/courses/${courseId}/instructor`
|
||||
@@ -17,19 +21,22 @@ export class GradebookHeader extends React.Component {
|
||||
href={this.lmsInstructorDashboardUrl(this.props.courseId)}
|
||||
className="mb-3"
|
||||
>
|
||||
<span aria-hidden="true">{'<< '}</span> Back to Dashboard
|
||||
<span aria-hidden="true">{'<< '}</span>
|
||||
<FormattedMessage {...messages.backToDashboard} />
|
||||
</a>
|
||||
<h1>Gradebook</h1>
|
||||
<h3> {this.props.courseId}</h3>
|
||||
<h1>
|
||||
<FormattedMessage {...messages.gradebook} />
|
||||
</h1>
|
||||
<h3>{this.props.courseId}</h3>
|
||||
{this.props.areGradesFrozen
|
||||
&& (
|
||||
<div className="alert alert-warning" role="alert">
|
||||
The grades for this course are now frozen. Editing of grades is no longer allowed.
|
||||
<FormattedMessage {...messages.frozenWarning} />
|
||||
</div>
|
||||
)}
|
||||
{(this.props.canUserViewGradebook === false) && (
|
||||
<div className="alert alert-warning" role="alert">
|
||||
You are not authorized to view the gradebook for this course.
|
||||
<FormattedMessage {...messages.unauthorizedWarning} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
26
src/components/GradebookHeader/messages.js
Normal file
26
src/components/GradebookHeader/messages.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||
|
||||
const messages = defineMessages({
|
||||
backToDashboard: {
|
||||
id: 'gradebook.GradebookHeader.backButton',
|
||||
defaultMessage: 'Back to Dashboard',
|
||||
description: 'Button text to take user back to LMS dashboard in Gradebook Header',
|
||||
},
|
||||
gradebook: {
|
||||
id: 'gradebook.GradebookHeader.appLabel',
|
||||
defaultMessage: 'Gradebook',
|
||||
description: 'Top-level app title in Gradebook Header component',
|
||||
},
|
||||
frozenWarning: {
|
||||
id: 'gradebook.GradebookHeader.frozenWarning',
|
||||
defaultMessage: 'The grades for this course are now frozen. Editing of grades is no longer allowed.',
|
||||
description: 'Warning message in Gradebook Header for frozen messages',
|
||||
},
|
||||
unauthorizedWarning: {
|
||||
id: 'gradebook.GradebookHeader.unauthorizedWarning',
|
||||
defaultMessage: 'You are not authorized to view the gradebook for this course.',
|
||||
description: 'Warning message in Gradebook Header when user is not allowed to view the app',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -4,6 +4,11 @@ import { shallow } from 'enzyme';
|
||||
import selectors from 'data/selectors';
|
||||
import { GradebookHeader, mapStateToProps } from '.';
|
||||
|
||||
jest.mock('@edx/frontend-platform/i18n', () => ({
|
||||
defineMessages: messages => messages,
|
||||
FormattedMessage: 'FormattedMessage',
|
||||
}));
|
||||
|
||||
jest.mock('data/selectors', () => ({
|
||||
__esModule: true,
|
||||
default: {
|
||||
|
||||
@@ -4,11 +4,14 @@ import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { StatefulButton, Icon } from '@edx/paragon';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { StrictDict } from 'utils';
|
||||
import actions from 'data/actions';
|
||||
import selectors from 'data/selectors';
|
||||
|
||||
import messages from './messages';
|
||||
|
||||
export const basicButtonProps = () => ({
|
||||
variant: 'outline-primary',
|
||||
icons: {
|
||||
@@ -63,11 +66,11 @@ export class BulkManagementControls extends React.Component {
|
||||
return this.props.showBulkManagement && (
|
||||
<div>
|
||||
<StatefulButton
|
||||
{...this.buttonProps('Bulk Management')}
|
||||
{...this.buttonProps(<FormattedMessage {...messages.bulkManagement} />)}
|
||||
onClick={this.handleClickExportGrades}
|
||||
/>
|
||||
<StatefulButton
|
||||
{...this.buttonProps('Interventions')}
|
||||
{...this.buttonProps(<FormattedMessage {...messages.interventions} />)}
|
||||
onClick={this.handleClickDownloadInterventions}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@ HistoryHeader.defaultProps = {
|
||||
};
|
||||
HistoryHeader.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
label: PropTypes.string.isRequired,
|
||||
label: PropTypes.node.isRequired,
|
||||
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,11 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import selectors from 'data/selectors';
|
||||
|
||||
import messages from './messages';
|
||||
import HistoryHeader from './HistoryHeader';
|
||||
|
||||
/**
|
||||
@@ -18,22 +22,22 @@ export const ModalHeaders = ({
|
||||
<div>
|
||||
<HistoryHeader
|
||||
id="assignment"
|
||||
label="Assignment"
|
||||
label={<FormattedMessage {...messages.assignmentHeader} />}
|
||||
value={modalState.assignmentName}
|
||||
/>
|
||||
<HistoryHeader
|
||||
id="student"
|
||||
label="Student"
|
||||
label={<FormattedMessage {...messages.studentHeader} />}
|
||||
value={modalState.updateUserName}
|
||||
/>
|
||||
<HistoryHeader
|
||||
id="original-grade"
|
||||
label="Original Grade"
|
||||
label={<FormattedMessage {...messages.originalGradeHeader} />}
|
||||
value={originalGrade}
|
||||
/>
|
||||
<HistoryHeader
|
||||
id="current-grade"
|
||||
label="Current Grade"
|
||||
label={<FormattedMessage {...messages.currentGradeHeader} />}
|
||||
value={currentGrade}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -6,19 +6,35 @@ exports[`OverrideTable Component snapshots basic snapshot shows a row for each e
|
||||
Array [
|
||||
Object {
|
||||
"key": "date",
|
||||
"label": "Date",
|
||||
"label": <FormattedMessage
|
||||
defaultMessage="Date"
|
||||
description="Edit Modal Override Table Date column header"
|
||||
id="gradebook.GradesTab.EditModal.Overrides.dateHeader"
|
||||
/>,
|
||||
},
|
||||
Object {
|
||||
"key": "grader",
|
||||
"label": "Grader",
|
||||
"label": <FormattedMessage
|
||||
defaultMessage="Grader"
|
||||
description="Edit Modal Override Table Grader column header"
|
||||
id="gradebook.GradesTab.EditModal.Overrides.graderHeader"
|
||||
/>,
|
||||
},
|
||||
Object {
|
||||
"key": "reason",
|
||||
"label": "Reason",
|
||||
"label": <FormattedMessage
|
||||
defaultMessage="Reason"
|
||||
description="Edit Modal Override Table Reason column header"
|
||||
id="gradebook.GradesTab.EditModal.Overrides.reasonHeader"
|
||||
/>,
|
||||
},
|
||||
Object {
|
||||
"key": "adjustedGrade",
|
||||
"label": "Adjusted grade",
|
||||
"label": <FormattedMessage
|
||||
defaultMessage="Adjusted grade"
|
||||
description="Edit Modal Override Table Adjusted grade column header"
|
||||
id="gradebook.GradesTab.EditModal.Overrides.adjustedGradeHeader"
|
||||
/>,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,18 +4,15 @@ import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { Table } from '@edx/paragon';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { gradeOverrideHistoryColumns as columns } from 'data/constants/app';
|
||||
import selectors from 'data/selectors';
|
||||
|
||||
import messages from './messages';
|
||||
import ReasonInput from './ReasonInput';
|
||||
import AdjustedGradeInput from './AdjustedGradeInput';
|
||||
|
||||
const GRADE_OVERRIDE_HISTORY_COLUMNS = [
|
||||
{ label: 'Date', key: 'date' },
|
||||
{ label: 'Grader', key: 'grader' },
|
||||
{ label: 'Reason', key: 'reason' },
|
||||
{ label: 'Adjusted grade', key: 'adjustedGrade' },
|
||||
];
|
||||
|
||||
/**
|
||||
* <OverrideTable />
|
||||
* Table containing previous grade override entries, and an "edit" row
|
||||
@@ -31,7 +28,15 @@ export const OverrideTable = ({
|
||||
}
|
||||
return (
|
||||
<Table
|
||||
columns={GRADE_OVERRIDE_HISTORY_COLUMNS}
|
||||
columns={[
|
||||
{ label: <FormattedMessage {...messages.dateHeader} />, key: columns.date },
|
||||
{ label: <FormattedMessage {...messages.graderHeader} />, key: columns.grader },
|
||||
{ label: <FormattedMessage {...messages.reasonHeader} />, key: columns.reason },
|
||||
{
|
||||
label: <FormattedMessage {...messages.adjustedGradeHeader} />,
|
||||
key: columns.adjustedGrade,
|
||||
},
|
||||
]}
|
||||
data={[
|
||||
...gradeOverrides,
|
||||
{
|
||||
|
||||
26
src/components/GradesTab/EditModal/OverrideTable/messages.js
Normal file
26
src/components/GradesTab/EditModal/OverrideTable/messages.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||
|
||||
const messages = defineMessages({
|
||||
adjustedGradeHeader: {
|
||||
id: 'gradebook.GradesTab.EditModal.Overrides.adjustedGradeHeader',
|
||||
defaultMessage: 'Adjusted grade',
|
||||
description: 'Edit Modal Override Table Adjusted grade column header',
|
||||
},
|
||||
dateHeader: {
|
||||
id: 'gradebook.GradesTab.EditModal.Overrides.dateHeader',
|
||||
defaultMessage: 'Date',
|
||||
description: 'Edit Modal Override Table Date column header',
|
||||
},
|
||||
graderHeader: {
|
||||
id: 'gradebook.GradesTab.EditModal.Overrides.graderHeader',
|
||||
defaultMessage: 'Grader',
|
||||
description: 'Edit Modal Override Table Grader column header',
|
||||
},
|
||||
reasonHeader: {
|
||||
id: 'gradebook.GradesTab.EditModal.Overrides.reasonHeader',
|
||||
defaultMessage: 'Reason',
|
||||
description: 'Edit Modal Override Table Reason column header',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -4,22 +4,46 @@ exports[`ModalHeaders Component snapshots gradeOverrideHistoryError is and empty
|
||||
<div>
|
||||
<HistoryHeader
|
||||
id="assignment"
|
||||
label="Assignment"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Assignment"
|
||||
description="Edit Modal Assignment header"
|
||||
id="gradebook.GradesTab.EditModal.headers.assignment"
|
||||
/>
|
||||
}
|
||||
value="Qwerty"
|
||||
/>
|
||||
<HistoryHeader
|
||||
id="student"
|
||||
label="Student"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Student"
|
||||
description="Edit Modal Student header"
|
||||
id="gradebook.GradesTab.EditModal.headers.student"
|
||||
/>
|
||||
}
|
||||
value="Uiop"
|
||||
/>
|
||||
<HistoryHeader
|
||||
id="original-grade"
|
||||
label="Original Grade"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Original Grade"
|
||||
description="Edit Modal Original Grade header"
|
||||
id="gradebook.GradesTab.EditModal.headers.originalGrade"
|
||||
/>
|
||||
}
|
||||
value={20}
|
||||
/>
|
||||
<HistoryHeader
|
||||
id="current-grade"
|
||||
label="Current Grade"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Current Grade"
|
||||
description="Edit Modal Current Grade header"
|
||||
id="gradebook.GradesTab.EditModal.headers.currentGrade"
|
||||
/>
|
||||
}
|
||||
value={2}
|
||||
/>
|
||||
</div>
|
||||
@@ -29,22 +53,46 @@ exports[`ModalHeaders Component snapshots gradeOverrideHistoryError is empty and
|
||||
<div>
|
||||
<HistoryHeader
|
||||
id="assignment"
|
||||
label="Assignment"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Assignment"
|
||||
description="Edit Modal Assignment header"
|
||||
id="gradebook.GradesTab.EditModal.headers.assignment"
|
||||
/>
|
||||
}
|
||||
value="Qwerty"
|
||||
/>
|
||||
<HistoryHeader
|
||||
id="student"
|
||||
label="Student"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Student"
|
||||
description="Edit Modal Student header"
|
||||
id="gradebook.GradesTab.EditModal.headers.student"
|
||||
/>
|
||||
}
|
||||
value="Uiop"
|
||||
/>
|
||||
<HistoryHeader
|
||||
id="original-grade"
|
||||
label="Original Grade"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Original Grade"
|
||||
description="Edit Modal Original Grade header"
|
||||
id="gradebook.GradesTab.EditModal.headers.originalGrade"
|
||||
/>
|
||||
}
|
||||
value={20}
|
||||
/>
|
||||
<HistoryHeader
|
||||
id="current-grade"
|
||||
label="Current Grade"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Current Grade"
|
||||
description="Edit Modal Current Grade header"
|
||||
id="gradebook.GradesTab.EditModal.headers.currentGrade"
|
||||
/>
|
||||
}
|
||||
value={2}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -13,10 +13,18 @@ exports[`EditMoal Component snapshots gradeOverrideHistoryError is and empty and
|
||||
/>
|
||||
<OverrideTable />
|
||||
<div>
|
||||
Showing most recent actions (max 5). To see more, please contact support.
|
||||
<FormattedMessage
|
||||
defaultMessage="Showing most recent actions (max 5). To see more, please contact support"
|
||||
description="Edit Modal visibility hint message"
|
||||
id="gradebook.GradesTab.EditModal.contactSupport"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
Note: Once you save, your changes will be visible to students.
|
||||
<FormattedMessage
|
||||
defaultMessage="Note: Once you save, your changes will be visible to students."
|
||||
description="Edit Modal saved changes effect hint"
|
||||
id="gradebook.GradesTab.EditModal.saveVisibility"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@@ -26,14 +34,30 @@ exports[`EditMoal Component snapshots gradeOverrideHistoryError is and empty and
|
||||
onClick={[MockFunction this.handleAdjustedGradeClick]}
|
||||
variant="primary"
|
||||
>
|
||||
Save Grade
|
||||
<FormattedMessage
|
||||
defaultMessage="Save Grades"
|
||||
description="Edit Modal Save button label"
|
||||
id="gradebook.GradesTab.EditModal.saveGrade"
|
||||
/>
|
||||
</Button>,
|
||||
]
|
||||
}
|
||||
closeText="Cancel"
|
||||
closeText={
|
||||
<FormattedMessage
|
||||
defaultMessage="Cancel"
|
||||
description="Edit Modal close button text"
|
||||
id="gradebook.GradesTab.EditModal.closeText"
|
||||
/>
|
||||
}
|
||||
onClose={[MockFunction this.closeAssignmentModal]}
|
||||
open={true}
|
||||
title="Edit Grades"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Edit Grades"
|
||||
description="Edit Modal title"
|
||||
id="gradebook.GradesTab.EditModal.title"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
`;
|
||||
|
||||
@@ -50,10 +74,18 @@ exports[`EditMoal Component snapshots gradeOverrideHistoryError is empty and ope
|
||||
/>
|
||||
<OverrideTable />
|
||||
<div>
|
||||
Showing most recent actions (max 5). To see more, please contact support.
|
||||
<FormattedMessage
|
||||
defaultMessage="Showing most recent actions (max 5). To see more, please contact support"
|
||||
description="Edit Modal visibility hint message"
|
||||
id="gradebook.GradesTab.EditModal.contactSupport"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
Note: Once you save, your changes will be visible to students.
|
||||
<FormattedMessage
|
||||
defaultMessage="Note: Once you save, your changes will be visible to students."
|
||||
description="Edit Modal saved changes effect hint"
|
||||
id="gradebook.GradesTab.EditModal.saveVisibility"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@@ -63,13 +95,29 @@ exports[`EditMoal Component snapshots gradeOverrideHistoryError is empty and ope
|
||||
onClick={[MockFunction this.handleAdjustedGradeClick]}
|
||||
variant="primary"
|
||||
>
|
||||
Save Grade
|
||||
<FormattedMessage
|
||||
defaultMessage="Save Grades"
|
||||
description="Edit Modal Save button label"
|
||||
id="gradebook.GradesTab.EditModal.saveGrade"
|
||||
/>
|
||||
</Button>,
|
||||
]
|
||||
}
|
||||
closeText="Cancel"
|
||||
closeText={
|
||||
<FormattedMessage
|
||||
defaultMessage="Cancel"
|
||||
description="Edit Modal close button text"
|
||||
id="gradebook.GradesTab.EditModal.closeText"
|
||||
/>
|
||||
}
|
||||
onClose={[MockFunction this.closeAssignmentModal]}
|
||||
open={false}
|
||||
title="Edit Grades"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Edit Grades"
|
||||
description="Edit Modal title"
|
||||
id="gradebook.GradesTab.EditModal.title"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
`;
|
||||
|
||||
@@ -8,11 +8,13 @@ import {
|
||||
Modal,
|
||||
StatusAlert,
|
||||
} from '@edx/paragon';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import selectors from 'data/selectors';
|
||||
import actions from 'data/actions';
|
||||
import thunkActions from 'data/thunkActions';
|
||||
|
||||
import messages from './messages';
|
||||
import OverrideTable from './OverrideTable';
|
||||
import ModalHeaders from './ModalHeaders';
|
||||
|
||||
@@ -46,8 +48,8 @@ export class EditModal extends React.Component {
|
||||
return (
|
||||
<Modal
|
||||
open={this.props.open}
|
||||
title="Edit Grades"
|
||||
closeText="Cancel"
|
||||
title={<FormattedMessage {...messages.title} />}
|
||||
closeText={<FormattedMessage {...messages.closeText} />}
|
||||
body={(
|
||||
<div>
|
||||
<ModalHeaders />
|
||||
@@ -58,15 +60,13 @@ export class EditModal extends React.Component {
|
||||
dismissible={false}
|
||||
/>
|
||||
<OverrideTable />
|
||||
<div>Showing most recent actions (max 5). To see more, please contact
|
||||
support.
|
||||
</div>
|
||||
<div>Note: Once you save, your changes will be visible to students.</div>
|
||||
<div><FormattedMessage {...messages.visibility} /></div>
|
||||
<div><FormattedMessage {...messages.saveVisibility} /></div>
|
||||
</div>
|
||||
)}
|
||||
buttons={[
|
||||
<Button variant="primary" onClick={this.handleAdjustedGradeClick}>
|
||||
Save Grade
|
||||
<FormattedMessage {...messages.saveGrade} />
|
||||
</Button>,
|
||||
]}
|
||||
onClose={this.closeAssignmentModal}
|
||||
|
||||
51
src/components/GradesTab/EditModal/messages.js
Normal file
51
src/components/GradesTab/EditModal/messages.js
Normal file
@@ -0,0 +1,51 @@
|
||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||
|
||||
const messages = defineMessages({
|
||||
assignmentHeader: {
|
||||
id: 'gradebook.GradesTab.EditModal.headers.assignment',
|
||||
defaultMessage: 'Assignment',
|
||||
description: 'Edit Modal Assignment header',
|
||||
},
|
||||
currentGradeHeader: {
|
||||
id: 'gradebook.GradesTab.EditModal.headers.currentGrade',
|
||||
defaultMessage: 'Current Grade',
|
||||
description: 'Edit Modal Current Grade header',
|
||||
},
|
||||
originalGradeHeader: {
|
||||
id: 'gradebook.GradesTab.EditModal.headers.originalGrade',
|
||||
defaultMessage: 'Original Grade',
|
||||
description: 'Edit Modal Original Grade header',
|
||||
},
|
||||
studentHeader: {
|
||||
id: 'gradebook.GradesTab.EditModal.headers.student',
|
||||
defaultMessage: 'Student',
|
||||
description: 'Edit Modal Student header',
|
||||
},
|
||||
title: {
|
||||
id: 'gradebook.GradesTab.EditModal.title',
|
||||
defaultMessage: 'Edit Grades',
|
||||
description: 'Edit Modal title',
|
||||
},
|
||||
closeText: {
|
||||
id: 'gradebook.GradesTab.EditModal.closeText',
|
||||
defaultMessage: 'Cancel',
|
||||
description: 'Edit Modal close button text',
|
||||
},
|
||||
visibility: {
|
||||
id: 'gradebook.GradesTab.EditModal.contactSupport',
|
||||
defaultMessage: 'Showing most recent actions (max 5). To see more, please contact support',
|
||||
description: 'Edit Modal visibility hint message',
|
||||
},
|
||||
saveVisibility: {
|
||||
id: 'gradebook.GradesTab.EditModal.saveVisibility',
|
||||
defaultMessage: 'Note: Once you save, your changes will be visible to students.',
|
||||
description: 'Edit Modal saved changes effect hint',
|
||||
},
|
||||
saveGrade: {
|
||||
id: 'gradebook.GradesTab.EditModal.saveGrade',
|
||||
defaultMessage: 'Save Grades',
|
||||
description: 'Edit Modal Save button label',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -3,6 +3,7 @@ import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { Button } from '@edx/paragon';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import selectors from 'data/selectors';
|
||||
|
||||
@@ -15,7 +16,6 @@ import selectors from 'data/selectors';
|
||||
* @param {string} filterName - api filter name (for redux connector)
|
||||
*/
|
||||
export const FilterBadge = ({
|
||||
handleClose,
|
||||
config: {
|
||||
displayName,
|
||||
isDefault,
|
||||
@@ -23,11 +23,15 @@ export const FilterBadge = ({
|
||||
value,
|
||||
connectedFilters,
|
||||
},
|
||||
handleClose,
|
||||
}) => !isDefault && (
|
||||
<div>
|
||||
<span className="badge badge-info">
|
||||
<span>
|
||||
{displayName}{!hideValue && `: ${value}`}
|
||||
<FormattedMessage {...displayName} />
|
||||
</span>
|
||||
<span>
|
||||
{!hideValue ? `: ${value}` : ''}
|
||||
</span>
|
||||
<Button
|
||||
className="btn-info"
|
||||
@@ -48,7 +52,9 @@ FilterBadge.propTypes = {
|
||||
// redux
|
||||
config: PropTypes.shape({
|
||||
connectedFilters: PropTypes.arrayOf(PropTypes.string),
|
||||
displayName: PropTypes.string.isRequired,
|
||||
displayName: PropTypes.shape({
|
||||
defaultMessage: PropTypes.string,
|
||||
}).isRequired,
|
||||
isDefault: PropTypes.bool.isRequired,
|
||||
hideValue: PropTypes.bool,
|
||||
value: PropTypes.oneOfType([
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { Button } from '@edx/paragon';
|
||||
import selectors from 'data/selectors';
|
||||
@@ -20,7 +21,9 @@ jest.mock('data/selectors', () => ({
|
||||
describe('FilterBadge', () => {
|
||||
describe('component', () => {
|
||||
const config = {
|
||||
displayName: 'a common name',
|
||||
displayName: {
|
||||
defaultMessage: 'a common name',
|
||||
},
|
||||
isDefault: false,
|
||||
hideValue: false,
|
||||
value: 'a common value',
|
||||
@@ -58,7 +61,11 @@ describe('FilterBadge', () => {
|
||||
expect(el).toMatchSnapshot();
|
||||
});
|
||||
it('shows displayName but not value in span', () => {
|
||||
expect(el.find('span.badge').childAt(0).text()).toEqual(config.displayName);
|
||||
expect(el.find('span.badge').childAt(0).getElement()).toEqual(
|
||||
<span>
|
||||
<FormattedMessage {...config.displayName} />
|
||||
</span>,
|
||||
);
|
||||
});
|
||||
it('calls a handleClose event for connected filters on button click', () => {
|
||||
expect(el.find(Button).props().onClick).toEqual(handleClose(config.connectedFilters));
|
||||
@@ -72,8 +79,15 @@ describe('FilterBadge', () => {
|
||||
expect(el).toMatchSnapshot();
|
||||
});
|
||||
it('shows displayName and value in span', () => {
|
||||
expect(el.find('span.badge').childAt(0).text()).toEqual(
|
||||
`${config.displayName}: ${config.value}`,
|
||||
expect(el.find('span.badge').childAt(0).getElement()).toEqual(
|
||||
<span>
|
||||
<FormattedMessage {...config.displayName} />
|
||||
</span>,
|
||||
);
|
||||
expect(el.find('span.badge').childAt(1).getElement()).toEqual(
|
||||
<span>
|
||||
{`: ${config.value}`}
|
||||
</span>,
|
||||
);
|
||||
});
|
||||
it('calls a handleClose event for connected filters on button click', () => {
|
||||
|
||||
@@ -8,7 +8,11 @@ exports[`FilterBadge component with non-default value (active) if hideValue is f
|
||||
className="badge badge-info"
|
||||
>
|
||||
<span>
|
||||
a common name
|
||||
<FormattedMessage
|
||||
defaultMessage="a common name"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
: a common value
|
||||
</span>
|
||||
<Button
|
||||
@@ -40,8 +44,11 @@ exports[`FilterBadge component with non-default value (active) if hideValue is t
|
||||
className="badge badge-info"
|
||||
>
|
||||
<span>
|
||||
a common name
|
||||
<FormattedMessage
|
||||
defaultMessage="a common name"
|
||||
/>
|
||||
</span>
|
||||
<span />
|
||||
<Button
|
||||
aria-label="close"
|
||||
className="btn-info"
|
||||
|
||||
@@ -7,8 +7,9 @@ import {
|
||||
OverlayTrigger,
|
||||
Tooltip,
|
||||
} from '@edx/paragon';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { Headings } from 'data/constants/grades';
|
||||
import messages from './messages';
|
||||
|
||||
export const totalGradePercentageMessage = 'Total Grade values are always displayed as a percentage.';
|
||||
|
||||
@@ -23,12 +24,21 @@ const TotalGradeLabelReplacement = () => (
|
||||
trigger={['hover', 'focus']}
|
||||
key="left-basic"
|
||||
placement="left"
|
||||
overlay={(<Tooltip id="course-grade-tooltip">{totalGradePercentageMessage}</Tooltip>)}
|
||||
overlay={(
|
||||
<Tooltip id="course-grade-tooltip">
|
||||
<FormattedMessage {...messages.totalGradePercentage} />
|
||||
</Tooltip>
|
||||
)}
|
||||
>
|
||||
<div>
|
||||
{Headings.totalGrade}
|
||||
<FormattedMessage {...messages.totalGradeHeading} />
|
||||
<div id="courseGradeTooltipIcon">
|
||||
<Icon className="fa fa-info-circle" screenReaderText={totalGradePercentageMessage} />
|
||||
<Icon
|
||||
className="fa fa-info-circle"
|
||||
screenReaderText={(
|
||||
<FormattedMessage {...messages.totalGradePercentage} />
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</OverlayTrigger>
|
||||
@@ -41,8 +51,12 @@ const TotalGradeLabelReplacement = () => (
|
||||
*/
|
||||
const UsernameLabelReplacement = () => (
|
||||
<div>
|
||||
<div>Username</div>
|
||||
<div className="font-weight-normal student-key">Student Key*</div>
|
||||
<div>
|
||||
<FormattedMessage {...messages.usernameHeading} />
|
||||
</div>
|
||||
<div className="font-weight-normal student-key">
|
||||
<FormattedMessage {...messages.studentKeyLabel} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@@ -4,7 +4,11 @@ exports[`LabelReplacements TotalGradeLabelReplacement displays overlay tooltip 1
|
||||
<Tooltip
|
||||
id="course-grade-tooltip"
|
||||
>
|
||||
Total Grade values are always displayed as a percentage.
|
||||
<FormattedMessage
|
||||
defaultMessage="Total Grade values are always displayed as a percentage"
|
||||
description="Gradebook table message that total grades are displayed in percent format"
|
||||
id="gradebook.GradesTab.table.totalGradePercentage"
|
||||
/>
|
||||
</Tooltip>
|
||||
`;
|
||||
|
||||
@@ -16,7 +20,11 @@ exports[`LabelReplacements TotalGradeLabelReplacement snapshot 1`] = `
|
||||
<Tooltip
|
||||
id="course-grade-tooltip"
|
||||
>
|
||||
Total Grade values are always displayed as a percentage.
|
||||
<FormattedMessage
|
||||
defaultMessage="Total Grade values are always displayed as a percentage"
|
||||
description="Gradebook table message that total grades are displayed in percent format"
|
||||
id="gradebook.GradesTab.table.totalGradePercentage"
|
||||
/>
|
||||
</Tooltip>
|
||||
}
|
||||
placement="left"
|
||||
@@ -28,13 +36,23 @@ exports[`LabelReplacements TotalGradeLabelReplacement snapshot 1`] = `
|
||||
}
|
||||
>
|
||||
<div>
|
||||
Total Grade (%)
|
||||
<FormattedMessage
|
||||
defaultMessage="Total Grade (%)"
|
||||
description="Gradebook table total grade column header"
|
||||
id="gradebook.GradesTab.table.headings.totalGrade"
|
||||
/>
|
||||
<div
|
||||
id="courseGradeTooltipIcon"
|
||||
>
|
||||
<Icon
|
||||
className="fa fa-info-circle"
|
||||
screenReaderText="Total Grade values are always displayed as a percentage."
|
||||
screenReaderText={
|
||||
<FormattedMessage
|
||||
defaultMessage="Total Grade values are always displayed as a percentage"
|
||||
description="Gradebook table message that total grades are displayed in percent format"
|
||||
id="gradebook.GradesTab.table.totalGradePercentage"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -45,12 +63,20 @@ exports[`LabelReplacements TotalGradeLabelReplacement snapshot 1`] = `
|
||||
exports[`LabelReplacements UsernameLabelReplacement snapshot 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
Username
|
||||
<FormattedMessage
|
||||
defaultMessage="Username"
|
||||
description="Gradebook table username column header"
|
||||
id="gradebook.GradesTab.table.headings.username"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="font-weight-normal student-key"
|
||||
>
|
||||
Student Key*
|
||||
<FormattedMessage
|
||||
defaultMessage="Student Key*"
|
||||
description="Gradebook table Student Key label"
|
||||
id="gradebook.GradesTab.table.labels.studentKey"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -16,7 +16,11 @@ exports[`GradebookTable component snapshot - fields1 and 2 between email and tot
|
||||
},
|
||||
Object {
|
||||
"key": "Email",
|
||||
"label": "Email",
|
||||
"label": <FormattedMessage
|
||||
defaultMessage="Email"
|
||||
description="Gradebook table email column header"
|
||||
id="gradebook.GradesTab.table.headings.email"
|
||||
/>,
|
||||
},
|
||||
Object {
|
||||
"key": "field1",
|
||||
|
||||
@@ -4,10 +4,12 @@ import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { Table } from '@edx/paragon';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { Headings } from 'data/constants/grades';
|
||||
import selectors from 'data/selectors';
|
||||
import { Headings } from 'data/constants/grades';
|
||||
|
||||
import messages from './messages';
|
||||
import Fields from './Fields';
|
||||
import LabelReplacements from './LabelReplacements';
|
||||
import GradeButton from './GradeButton';
|
||||
@@ -28,14 +30,17 @@ export class GradebookTable extends React.Component {
|
||||
}
|
||||
|
||||
mapHeaders(heading) {
|
||||
const replacement = {
|
||||
[Headings.totalGrade]: <LabelReplacements.TotalGradeLabelReplacement />,
|
||||
[Headings.username]: <LabelReplacements.UsernameLabelReplacement />,
|
||||
}[heading];
|
||||
return {
|
||||
label: replacement !== undefined ? replacement : heading,
|
||||
key: heading,
|
||||
};
|
||||
let label;
|
||||
if (heading === Headings.totalGrade) {
|
||||
label = <LabelReplacements.TotalGradeLabelReplacement />;
|
||||
} else if (heading === Headings.username) {
|
||||
label = <LabelReplacements.UsernameLabelReplacement />;
|
||||
} else if (heading === Headings.email) {
|
||||
label = <FormattedMessage {...messages.emailHeading} />;
|
||||
} else {
|
||||
label = heading;
|
||||
}
|
||||
return { label, key: heading };
|
||||
}
|
||||
|
||||
mapRows(entry) {
|
||||
|
||||
36
src/components/GradesTab/GradebookTable/messages.js
Normal file
36
src/components/GradesTab/GradebookTable/messages.js
Normal file
@@ -0,0 +1,36 @@
|
||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||
|
||||
const messages = defineMessages({
|
||||
emailHeading: {
|
||||
id: 'gradebook.GradesTab.table.headings.email',
|
||||
defaultMessage: 'Email',
|
||||
description: 'Gradebook table email column header',
|
||||
},
|
||||
totalGradeHeading: {
|
||||
id: 'gradebook.GradesTab.table.headings.totalGrade',
|
||||
defaultMessage: 'Total Grade (%)',
|
||||
description: 'Gradebook table total grade column header',
|
||||
},
|
||||
usernameHeading: {
|
||||
id: 'gradebook.GradesTab.table.headings.username',
|
||||
defaultMessage: 'Username',
|
||||
description: 'Gradebook table username column header',
|
||||
},
|
||||
studentKeyLabel: {
|
||||
id: 'gradebook.GradesTab.table.labels.studentKey',
|
||||
defaultMessage: 'Student Key*',
|
||||
description: 'Gradebook table Student Key label',
|
||||
},
|
||||
usernameLabel: {
|
||||
id: 'gradebook.GradesTab.table.labels.username',
|
||||
defaultMessage: 'Username',
|
||||
description: 'Gradebook table username label',
|
||||
},
|
||||
totalGradePercentage: {
|
||||
id: 'gradebook.GradesTab.table.totalGradePercentage',
|
||||
defaultMessage: 'Total Grade values are always displayed as a percentage',
|
||||
description: 'Gradebook table message that total grades are displayed in percent format',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -2,11 +2,13 @@ import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { Table } from '@edx/paragon';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import selectors from 'data/selectors';
|
||||
import { Headings } from 'data/constants/grades';
|
||||
import LabelReplacements from './LabelReplacements';
|
||||
import Fields from './Fields';
|
||||
import messages from './messages';
|
||||
import { GradebookTable, mapStateToProps } from '.';
|
||||
|
||||
jest.mock('@edx/paragon', () => ({
|
||||
@@ -94,7 +96,7 @@ describe('GradebookTable', () => {
|
||||
test('email sets key and label from header', () => {
|
||||
const heading = headings[1];
|
||||
expect(heading.key).toEqual(Headings.email);
|
||||
expect(heading.label).toEqual(Headings.email);
|
||||
expect(heading.label).toEqual(<FormattedMessage {...messages.emailHeading} />);
|
||||
});
|
||||
test('subsections set key and label from header', () => {
|
||||
expect(headings[2]).toEqual({ key: fields.field1, label: fields.field1 });
|
||||
|
||||
@@ -19,7 +19,11 @@ exports[`PageButtons component snapshots buttons enabled with both endpoints pro
|
||||
}
|
||||
variant="outline-primary"
|
||||
>
|
||||
Previous Page
|
||||
<FormattedMessage
|
||||
defaultMessage="Previous Page"
|
||||
description="Grades tab Previous Page button text"
|
||||
id="gradebook.GradesTab.PageButtons.prevPage"
|
||||
/>
|
||||
</Button>
|
||||
<Button
|
||||
disabled={false}
|
||||
@@ -31,7 +35,11 @@ exports[`PageButtons component snapshots buttons enabled with both endpoints pro
|
||||
}
|
||||
variant="outline-primary"
|
||||
>
|
||||
Next Page
|
||||
<FormattedMessage
|
||||
defaultMessage="Next Page"
|
||||
description="Grades tab Next Page button text"
|
||||
id="gradebook.GradesTab.PageButtons.nextPage"
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
`;
|
||||
@@ -55,7 +63,11 @@ exports[`PageButtons component snapshots nextPage disabled if not provided 1`] =
|
||||
}
|
||||
variant="outline-primary"
|
||||
>
|
||||
Previous Page
|
||||
<FormattedMessage
|
||||
defaultMessage="Previous Page"
|
||||
description="Grades tab Previous Page button text"
|
||||
id="gradebook.GradesTab.PageButtons.prevPage"
|
||||
/>
|
||||
</Button>
|
||||
<Button
|
||||
disabled={true}
|
||||
@@ -67,7 +79,11 @@ exports[`PageButtons component snapshots nextPage disabled if not provided 1`] =
|
||||
}
|
||||
variant="outline-primary"
|
||||
>
|
||||
Next Page
|
||||
<FormattedMessage
|
||||
defaultMessage="Next Page"
|
||||
description="Grades tab Next Page button text"
|
||||
id="gradebook.GradesTab.PageButtons.nextPage"
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
`;
|
||||
@@ -91,7 +107,11 @@ exports[`PageButtons component snapshots prevPage disabled if not provided 1`] =
|
||||
}
|
||||
variant="outline-primary"
|
||||
>
|
||||
Previous Page
|
||||
<FormattedMessage
|
||||
defaultMessage="Previous Page"
|
||||
description="Grades tab Previous Page button text"
|
||||
id="gradebook.GradesTab.PageButtons.prevPage"
|
||||
/>
|
||||
</Button>
|
||||
<Button
|
||||
disabled={false}
|
||||
@@ -103,7 +123,11 @@ exports[`PageButtons component snapshots prevPage disabled if not provided 1`] =
|
||||
}
|
||||
variant="outline-primary"
|
||||
>
|
||||
Next Page
|
||||
<FormattedMessage
|
||||
defaultMessage="Next Page"
|
||||
description="Grades tab Next Page button text"
|
||||
id="gradebook.GradesTab.PageButtons.nextPage"
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -3,9 +3,11 @@ import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { Button } from '@edx/paragon';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import selectors from 'data/selectors';
|
||||
import thunkActions from 'data/thunkActions';
|
||||
import messages from './messages';
|
||||
|
||||
export class PageButtons extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -34,7 +36,7 @@ export class PageButtons extends React.Component {
|
||||
disabled={!this.props.prevPage}
|
||||
onClick={this.getPrevGrades}
|
||||
>
|
||||
Previous Page
|
||||
<FormattedMessage {...messages.prevPage} />
|
||||
</Button>
|
||||
<Button
|
||||
style={{ margin: '20px' }}
|
||||
@@ -42,7 +44,7 @@ export class PageButtons extends React.Component {
|
||||
disabled={!this.props.nextPage}
|
||||
onClick={this.getNextGrades}
|
||||
>
|
||||
Next Page
|
||||
<FormattedMessage {...messages.nextPage} />
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
16
src/components/GradesTab/PageButtons/messages.js
Normal file
16
src/components/GradesTab/PageButtons/messages.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||
|
||||
const messages = defineMessages({
|
||||
prevPage: {
|
||||
id: 'gradebook.GradesTab.PageButtons.prevPage',
|
||||
defaultMessage: 'Previous Page',
|
||||
description: 'Grades tab Previous Page button text',
|
||||
},
|
||||
nextPage: {
|
||||
id: 'gradebook.GradesTab.PageButtons.nextPage',
|
||||
defaultMessage: 'Next Page',
|
||||
description: 'Grades tab Next Page button text',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -3,29 +3,37 @@ import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { FormControl, FormGroup, FormLabel } from '@edx/paragon';
|
||||
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import actions from 'data/actions';
|
||||
import selectors from 'data/selectors';
|
||||
import messages from './messages';
|
||||
|
||||
/**
|
||||
* <ScoreViewInput />
|
||||
* redux-connected select control for grade format (percent vs absolute)
|
||||
*/
|
||||
export const ScoreViewInput = ({ format, toggleFormat }) => (
|
||||
export const ScoreViewInput = ({ format, intl, toggleFormat }) => (
|
||||
<FormGroup controlId="ScoreView">
|
||||
<FormLabel>Score View:</FormLabel>
|
||||
<FormLabel><FormattedMessage {...messages.scoreView} />:</FormLabel>
|
||||
<FormControl
|
||||
as="select"
|
||||
value={format}
|
||||
onChange={toggleFormat}
|
||||
>
|
||||
<option value="percent">Percent</option>
|
||||
<option value="absolute">Absolute</option>
|
||||
<option value="percent">{intl.formatMessage(messages.percent)}</option>
|
||||
<option value="absolute">{intl.formatMessage(messages.absolute)}</option>
|
||||
</FormControl>
|
||||
</FormGroup>
|
||||
);
|
||||
ScoreViewInput.defaultProps = {
|
||||
format: 'percent',
|
||||
};
|
||||
ScoreViewInput.propTypes = {
|
||||
format: PropTypes.string.isRequired,
|
||||
// injected
|
||||
intl: intlShape.isRequired,
|
||||
// redux
|
||||
format: PropTypes.string,
|
||||
toggleFormat: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
@@ -37,4 +45,4 @@ export const mapDispatchToProps = {
|
||||
toggleFormat: actions.grades.toggleGradeFormat,
|
||||
};
|
||||
|
||||
export default connect(() => ({}), mapDispatchToProps)(ScoreViewInput);
|
||||
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ScoreViewInput));
|
||||
|
||||
@@ -35,6 +35,7 @@ describe('ScoreViewInput', () => {
|
||||
let el;
|
||||
beforeEach(() => {
|
||||
props.toggleFormat = jest.fn();
|
||||
props.intl = { formatMessage: (msg) => msg.defaultMessage };
|
||||
el = shallow(<ScoreViewInput {...props} />);
|
||||
});
|
||||
const assertions = [
|
||||
|
||||
@@ -3,11 +3,14 @@ import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { Button, Icon, SearchField } from '@edx/paragon';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import actions from 'data/actions';
|
||||
import selectors from 'data/selectors';
|
||||
import thunkActions from 'data/thunkActions';
|
||||
|
||||
import messages from './messages';
|
||||
|
||||
/**
|
||||
* Controls for filtering the GradebookTable. Contains the "Edit Filters" button for opening the filter drawer
|
||||
* as well as the search box for searching by username/email.
|
||||
@@ -32,25 +35,25 @@ export class SearchControls extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
<h4>Step 1: Filter the Grade Report</h4>
|
||||
<h4><FormattedMessage {...messages.filterStepHeading} /></h4>
|
||||
<div className="d-flex justify-content-between">
|
||||
<Button
|
||||
id="edit-filters-btn"
|
||||
className="btn-primary align-self-start"
|
||||
onClick={this.props.toggleFilterDrawer}
|
||||
>
|
||||
<Icon className="fa fa-filter" /> Edit Filters
|
||||
<Icon className="fa fa-filter" /> <FormattedMessage {...messages.editFilters} />
|
||||
</Button>
|
||||
<div>
|
||||
<SearchField
|
||||
onSubmit={this.props.fetchGrades}
|
||||
inputLabel="Search for a learner"
|
||||
inputLabel={<FormattedMessage {...messages.searchLabel} />}
|
||||
onChange={this.onChange}
|
||||
onClear={this.onClear}
|
||||
value={this.props.searchValue}
|
||||
/>
|
||||
<small className="form-text text-muted search-help-text">
|
||||
Search by username, email, or student key
|
||||
<FormattedMessage {...messages.searchHint} />
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,12 +3,11 @@ import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { StatusAlert } from '@edx/paragon';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import selectors from 'data/selectors';
|
||||
import actions from 'data/actions';
|
||||
|
||||
export const maxCourseGradeInvalidMessage = 'Maximum course grade value must be between 0 and 100. ';
|
||||
export const minCourseGradeInvalidMessage = 'Minimum course grade value must be between 0 and 100. ';
|
||||
import messages from './messages';
|
||||
|
||||
export class StatusAlerts extends React.Component {
|
||||
get isCourseGradeFilterAlertOpen() {
|
||||
@@ -18,15 +17,24 @@ export class StatusAlerts extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
get minValidityMessage() {
|
||||
return (this.props.limitValidity.isMinValid)
|
||||
? ''
|
||||
: <FormattedMessage {...messages.minGradeInvalid} />;
|
||||
}
|
||||
|
||||
get maxValidityMessage() {
|
||||
return (this.props.limitValidity.isMaxValid)
|
||||
? ''
|
||||
: <FormattedMessage {...messages.maxGradeInvalid} />;
|
||||
}
|
||||
|
||||
get courseGradeFilterAlertDialogText() {
|
||||
let dialogText = '';
|
||||
if (!this.props.limitValidity.isMinValid) {
|
||||
dialogText += minCourseGradeInvalidMessage;
|
||||
}
|
||||
if (!this.props.limitValidity.isMaxValid) {
|
||||
dialogText += maxCourseGradeInvalidMessage;
|
||||
}
|
||||
return dialogText;
|
||||
return (
|
||||
<>
|
||||
{this.minValidityMessage}{this.maxValidityMessage}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -34,7 +42,7 @@ export class StatusAlerts extends React.Component {
|
||||
<>
|
||||
<StatusAlert
|
||||
alertType="success"
|
||||
dialog="The grade has been successfully edited. You may see a slight delay before updates appear in the Gradebook."
|
||||
dialog={<FormattedMessage {...messages.editSuccessAlert} />}
|
||||
onClose={this.props.handleCloseSuccessBanner}
|
||||
open={this.props.showSuccessBanner}
|
||||
/>
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import actions from 'data/actions';
|
||||
import selectors from 'data/selectors';
|
||||
import messages from './messages';
|
||||
import {
|
||||
StatusAlerts,
|
||||
mapDispatchToProps,
|
||||
mapStateToProps,
|
||||
maxCourseGradeInvalidMessage,
|
||||
minCourseGradeInvalidMessage,
|
||||
} from './StatusAlerts';
|
||||
|
||||
jest.mock('@edx/paragon', () => ({
|
||||
@@ -77,18 +78,24 @@ describe('StatusAlerts', () => {
|
||||
!isMinValid || !isMaxValid,
|
||||
);
|
||||
if (!isMaxValid) {
|
||||
if (!isMinValid) {
|
||||
expect(el.instance().courseGradeFilterAlertDialogText).toEqual(
|
||||
<>
|
||||
<FormattedMessage {...messages.minGradeInvalid} />
|
||||
<FormattedMessage {...messages.maxGradeInvalid} />
|
||||
</>,
|
||||
);
|
||||
} else {
|
||||
expect(
|
||||
el.instance().courseGradeFilterAlertDialogText,
|
||||
// eslint-disable-next-line react/jsx-curly-brace-presence
|
||||
).toEqual(<>{''}<FormattedMessage {...messages.maxGradeInvalid} /></>);
|
||||
}
|
||||
} else if (!isMinValid) {
|
||||
expect(
|
||||
el.instance().courseGradeFilterAlertDialogText,
|
||||
).toEqual(
|
||||
expect.stringContaining(maxCourseGradeInvalidMessage),
|
||||
);
|
||||
}
|
||||
if (!isMinValid) {
|
||||
expect(
|
||||
el.instance().courseGradeFilterAlertDialogText,
|
||||
).toEqual(
|
||||
expect.stringContaining(minCourseGradeInvalidMessage),
|
||||
);
|
||||
// eslint-disable-next-line react/jsx-curly-brace-presence
|
||||
).toEqual(<><FormattedMessage {...messages.minGradeInvalid} />{''}</>);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,8 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import selectors from 'data/selectors';
|
||||
|
||||
/**
|
||||
@@ -18,9 +20,15 @@ export const UsersLabel = ({
|
||||
}
|
||||
const bold = (val) => (<span className="font-weight-bold">{val}</span>);
|
||||
return (
|
||||
<>
|
||||
Showing {bold(filteredUsersCount)} of {bold(totalUsersCount)} total learners
|
||||
</>
|
||||
<FormattedMessage
|
||||
id="gradebook.GradesTab.usersVisibilityLabel'"
|
||||
defaultMessage="Showing {filteredUsers} of {totalUsers} total learners"
|
||||
description="Users visibility label"
|
||||
values={{
|
||||
filteredUsers: bold(filteredUsersCount),
|
||||
totalUsers: bold(totalUsersCount),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
UsersLabel.propTypes = {
|
||||
|
||||
@@ -5,7 +5,12 @@ exports[`ScoreViewInput component snapshot - select box with percent and absolut
|
||||
controlId="ScoreView"
|
||||
>
|
||||
<FormLabel>
|
||||
Score View:
|
||||
<FormattedMessage
|
||||
defaultMessage="Score View"
|
||||
description="Score format select dropdown label"
|
||||
id="gradebook.GradesTab.scoreViewLabel"
|
||||
/>
|
||||
:
|
||||
</FormLabel>
|
||||
<FormControl
|
||||
as="select"
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
exports[`SearchControls Component Snapshots basic snapshot 1`] = `
|
||||
<React.Fragment>
|
||||
<h4>
|
||||
Step 1: Filter the Grade Report
|
||||
<FormattedMessage
|
||||
defaultMessage="Step 1: Filter the Grade Report"
|
||||
description="Filter controls container heading string"
|
||||
id="gradebook.GradesTab.filterHeading"
|
||||
/>
|
||||
</h4>
|
||||
<div
|
||||
className="d-flex justify-content-between"
|
||||
@@ -16,11 +20,22 @@ exports[`SearchControls Component Snapshots basic snapshot 1`] = `
|
||||
<Icon
|
||||
className="fa fa-filter"
|
||||
/>
|
||||
Edit Filters
|
||||
|
||||
<FormattedMessage
|
||||
defaultMessage="Edit Filters"
|
||||
description="Button text on Grades tab to open/close the Filters tab"
|
||||
id="gradebook.GradesTab.editFilterLabel"
|
||||
/>
|
||||
</Button>
|
||||
<div>
|
||||
<SearchField
|
||||
inputLabel="Search for a learner"
|
||||
inputLabel={
|
||||
<FormattedMessage
|
||||
defaultMessage="Search for a learner"
|
||||
description="Search description label"
|
||||
id="gradebook.GradesTab.search.label"
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction onChange]}
|
||||
onClear={[MockFunction onClear]}
|
||||
onSubmit={[MockFunction fetchGrades]}
|
||||
@@ -29,7 +44,11 @@ exports[`SearchControls Component Snapshots basic snapshot 1`] = `
|
||||
<small
|
||||
className="form-text text-muted search-help-text"
|
||||
>
|
||||
Search by username, email, or student key
|
||||
<FormattedMessage
|
||||
defaultMessage="Search by username, email, or student key"
|
||||
description="Search hint label"
|
||||
id="gradebook.GradesTab.search.hint"
|
||||
/>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,13 @@ exports[`StatusAlerts snapshots basic snapshot 1`] = `
|
||||
<React.Fragment>
|
||||
<StatusAlert
|
||||
alertType="success"
|
||||
dialog="The grade has been successfully edited. You may see a slight delay before updates appear in the Gradebook."
|
||||
dialog={
|
||||
<FormattedMessage
|
||||
defaultMessage="The grade has been successfully edited. You may see a slight delay before updates appear in the Gradebook."
|
||||
description="Alert text for successful edit action"
|
||||
id="gradebook.GradesTab.editSuccessAlert"
|
||||
/>
|
||||
}
|
||||
onClose={[MockFunction handleCloseSuccessBanner]}
|
||||
open={true}
|
||||
/>
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`UsersLabel component snapshot - displays label with number of filtered users out of total 1`] = `
|
||||
<Fragment>
|
||||
Showing
|
||||
<span
|
||||
className="font-weight-bold"
|
||||
>
|
||||
23
|
||||
</span>
|
||||
of
|
||||
<span
|
||||
className="font-weight-bold"
|
||||
>
|
||||
140
|
||||
</span>
|
||||
total learners
|
||||
</Fragment>
|
||||
<FormattedMessage
|
||||
defaultMessage="Showing {filteredUsers} of {totalUsers} total learners"
|
||||
description="Users visibility label"
|
||||
id="gradebook.GradesTab.usersVisibilityLabel'"
|
||||
values={
|
||||
Object {
|
||||
"filteredUsers": <span
|
||||
className="font-weight-bold"
|
||||
>
|
||||
23
|
||||
</span>,
|
||||
"totalUsers": <span
|
||||
className="font-weight-bold"
|
||||
>
|
||||
140
|
||||
</span>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
`;
|
||||
|
||||
@@ -9,7 +9,11 @@ exports[`GradesTab Component snapshots basic snapshot 1`] = `
|
||||
/>
|
||||
<StatusAlerts />
|
||||
<h4>
|
||||
Step 2: View or Modify Individual Grades
|
||||
<FormattedMessage
|
||||
defaultMessage="Step 2: View or Modify Individual Grades"
|
||||
description="Alert text for invalid minimum course grade"
|
||||
id="gradebook.GradesTab.gradebookStepHeading"
|
||||
/>
|
||||
</h4>
|
||||
<UsersLabel />
|
||||
<div
|
||||
@@ -21,7 +25,12 @@ exports[`GradesTab Component snapshots basic snapshot 1`] = `
|
||||
<GradebookTable />
|
||||
<PageButtons />
|
||||
<p>
|
||||
* available for learners in the Master's track only
|
||||
*
|
||||
<FormattedMessage
|
||||
defaultMessage="available for learners in the Master's track only"
|
||||
description="Masters feature availability hint on Grades Tab"
|
||||
id="gradebook.GradesTab.mastersHint"
|
||||
/>
|
||||
</p>
|
||||
<EditModal />
|
||||
</React.Fragment>
|
||||
|
||||
@@ -3,6 +3,8 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import actions from 'data/actions';
|
||||
import thunkActions from 'data/thunkActions';
|
||||
|
||||
@@ -17,6 +19,7 @@ import StatusAlerts from './StatusAlerts';
|
||||
import SpinnerIcon from './SpinnerIcon';
|
||||
import ScoreViewInput from './ScoreViewInput';
|
||||
import UsersLabel from './UsersLabel';
|
||||
import messages from './messages';
|
||||
|
||||
export class GradesTab extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -43,7 +46,7 @@ export class GradesTab extends React.Component {
|
||||
<FilterBadges handleClose={this.handleFilterBadgeClose} />
|
||||
<StatusAlerts />
|
||||
|
||||
<h4>Step 2: View or Modify Individual Grades</h4>
|
||||
<h4><FormattedMessage {...messages.gradebookStepHeading} /></h4>
|
||||
<UsersLabel />
|
||||
|
||||
<div className="d-flex justify-content-between align-items-center mb-2">
|
||||
@@ -54,7 +57,7 @@ export class GradesTab extends React.Component {
|
||||
<GradebookTable />
|
||||
|
||||
<PageButtons />
|
||||
<p>* available for learners in the Master's track only</p>
|
||||
<p>* <FormattedMessage {...messages.mastersHint} /></p>
|
||||
<EditModal />
|
||||
</>
|
||||
);
|
||||
|
||||
76
src/components/GradesTab/messages.js
Normal file
76
src/components/GradesTab/messages.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||
|
||||
const messages = defineMessages({
|
||||
bulkManagement: {
|
||||
id: 'gradebook.GradesTab.BulkManagementControls.bulkManagementLabel',
|
||||
defaultMessage: 'Bulk Management',
|
||||
description: 'Button text for bulk grades download control in GradesTab',
|
||||
},
|
||||
interventions: {
|
||||
id: 'gradebook.GradesTab.BulkManagementControls.interventionsLabel',
|
||||
defaultMessage: 'Interventions',
|
||||
description: 'Button text for intervention report download control in GradesTab',
|
||||
},
|
||||
scoreView: {
|
||||
id: 'gradebook.GradesTab.scoreViewLabel',
|
||||
defaultMessage: 'Score View',
|
||||
description: 'Score format select dropdown label',
|
||||
},
|
||||
absolute: {
|
||||
id: 'gradebook.GradesTab.absoluteOption',
|
||||
defaultMessage: 'Absolute',
|
||||
description: 'Score format select dropdown option',
|
||||
},
|
||||
percent: {
|
||||
id: 'gradebook.GradesTab.percentOption',
|
||||
defaultMessage: 'Percent',
|
||||
description: 'Score format select dropdown option',
|
||||
},
|
||||
filterStepHeading: {
|
||||
id: 'gradebook.GradesTab.filterHeading',
|
||||
defaultMessage: 'Step 1: Filter the Grade Report',
|
||||
description: 'Filter controls container heading string',
|
||||
},
|
||||
editFilters: {
|
||||
id: 'gradebook.GradesTab.editFilterLabel',
|
||||
defaultMessage: 'Edit Filters',
|
||||
description: 'Button text on Grades tab to open/close the Filters tab',
|
||||
},
|
||||
searchLabel: {
|
||||
id: 'gradebook.GradesTab.search.label',
|
||||
defaultMessage: 'Search for a learner',
|
||||
description: 'Search description label',
|
||||
},
|
||||
searchHint: {
|
||||
id: 'gradebook.GradesTab.search.hint',
|
||||
defaultMessage: 'Search by username, email, or student key',
|
||||
description: 'Search hint label',
|
||||
},
|
||||
editSuccessAlert: {
|
||||
id: 'gradebook.GradesTab.editSuccessAlert',
|
||||
defaultMessage: 'The grade has been successfully edited. You may see a slight delay before updates appear in the Gradebook.',
|
||||
description: 'Alert text for successful edit action',
|
||||
},
|
||||
maxGradeInvalid: {
|
||||
id: 'gradebook.GradesTab.maxCourseGradeInvalid',
|
||||
defaultMessage: 'Maximum course grade must be between 0 and 100',
|
||||
description: 'Alert text for invalid maximum course grade',
|
||||
},
|
||||
minGradeInvalid: {
|
||||
id: 'gradebook.GradesTab.minCourseGradeInvalid',
|
||||
defaultMessage: 'Minimum course grade must be between 0 and 100',
|
||||
description: 'Alert text for invalid minimum course grade',
|
||||
},
|
||||
gradebookStepHeading: {
|
||||
id: 'gradebook.GradesTab.gradebookStepHeading',
|
||||
defaultMessage: 'Step 2: View or Modify Individual Grades',
|
||||
description: 'Alert text for invalid minimum course grade',
|
||||
},
|
||||
mastersHint: {
|
||||
id: 'gradebook.GradesTab.mastersHint',
|
||||
defaultMessage: "available for learners in the Master's track only",
|
||||
description: 'Masters feature availability hint on Grades Tab',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -6,6 +6,7 @@ import thunkActions from 'data/thunkActions';
|
||||
|
||||
import {
|
||||
GradesTab,
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
} from '.';
|
||||
|
||||
@@ -78,6 +79,9 @@ describe('GradesTab', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
test('mapStateToProps is empty', () => {
|
||||
expect(mapStateToProps({ some: 'state' })).toEqual({});
|
||||
});
|
||||
describe('mapDispatchToProps', () => {
|
||||
describe('fetchGrades', () => {
|
||||
test('from thunkActions.grades.fetchGrades', () => {
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
import { createAction } from '@reduxjs/toolkit';
|
||||
|
||||
export const options = {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
timeZone: 'UTC',
|
||||
};
|
||||
export const timeOptions = {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
timeZone: 'UTC',
|
||||
timeZoneName: 'short',
|
||||
};
|
||||
|
||||
const formatDateForDisplay = (inputDate) => {
|
||||
const options = {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
timeZone: 'UTC',
|
||||
};
|
||||
const timeOptions = {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
timeZone: 'UTC',
|
||||
timeZoneName: 'short',
|
||||
};
|
||||
return `${inputDate.toLocaleDateString('en-US', options)} at ${inputDate.toLocaleTimeString('en-US', timeOptions)}`;
|
||||
const date = inputDate.toLocaleDateString('en-US', options);
|
||||
const time = inputDate.toLocaleTimeString('en-US', timeOptions);
|
||||
return `${date} at ${time}`;
|
||||
};
|
||||
|
||||
const sortAlphaAsc = (gradeRowA, gradeRowB) => {
|
||||
|
||||
34
src/data/actions/utils.test.js
Normal file
34
src/data/actions/utils.test.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import { createAction } from '@reduxjs/toolkit';
|
||||
import * as utils from './utils';
|
||||
|
||||
jest.mock('@reduxjs/toolkit', () => ({
|
||||
createAction: (key, ...args) => ({ action: key, args }),
|
||||
}));
|
||||
|
||||
describe('redux action utils', () => {
|
||||
describe('formatDateForDisplay', () => {
|
||||
it('returns the datetime as a formatted string', () => {
|
||||
expect(utils.formatDateForDisplay(new Date('Jun 3 2021 11:59 AM EDT'))).toEqual(
|
||||
'June 3, 2021 at 03:59 PM UTC',
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('sortAlphaAsc', () => {
|
||||
it('returns sorting value (-1, 0, 1) by uppercase username', () => {
|
||||
const sort = (v1, v2) => utils.sortAlphaAsc({ username: v1 }, { username: v2 });
|
||||
expect(sort('aName', 'ANAme')).toEqual(0);
|
||||
expect(sort('aName', 'laterName')).toEqual(-1);
|
||||
expect(sort('laterName', 'aName')).toEqual(1);
|
||||
});
|
||||
});
|
||||
describe('createActionFactory', () => {
|
||||
it('returns an action creator with the data key', () => {
|
||||
const dataKey = 'part-of-the-model';
|
||||
const actionKey = 'an-action';
|
||||
const args = ['some', 'args'];
|
||||
expect(utils.createActionFactory(dataKey)(actionKey, ...args)).toEqual(
|
||||
createAction(`${dataKey}/${actionKey}`, ...args),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,14 +0,0 @@
|
||||
import { configuration } from 'config';
|
||||
|
||||
export const baseUrl = `${configuration.LMS_BASE_URL}/api`;
|
||||
|
||||
/**
|
||||
* bulkGradesUrlByCourseAndRow(courseId, rowId)
|
||||
* returns the bulkGrades url with the given courseId and rowId.
|
||||
* @param {string} courseId - course identifier
|
||||
* @param {string} rowId - row/error identifier
|
||||
* @return {string} - bulk grades fetch url
|
||||
*/
|
||||
export const bulkGradesUrlByCourseAndRow = (courseId, rowId) => (
|
||||
`${baseUrl}/bulkGrades/course/${courseId}/?error_id=${rowId}`
|
||||
);
|
||||
@@ -1,4 +1,7 @@
|
||||
import { StrictDict } from 'utils';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
|
||||
export const routePath = `${getConfig().PUBLIC_PATH}:courseId`;
|
||||
|
||||
export const modalFieldKeys = StrictDict({
|
||||
adjustedGradePossible: 'adjustedGradePossible',
|
||||
@@ -49,6 +52,13 @@ export const bulkManagementColumns = [
|
||||
},
|
||||
];
|
||||
|
||||
export const gradeOverrideHistoryColumns = StrictDict({
|
||||
adjustedGrade: 'adjustedGrade',
|
||||
date: 'date',
|
||||
grader: 'grader',
|
||||
reason: 'reason',
|
||||
});
|
||||
|
||||
/**
|
||||
* Display strings for various app components.
|
||||
* Note: this is a temporary storage location for these strings, before we put them in
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { StrictDict } from 'utils';
|
||||
|
||||
import messages from './filters.messages';
|
||||
|
||||
export const filters = StrictDict({
|
||||
assignment: 'assignment',
|
||||
assignmentGrade: 'assignmentGrade',
|
||||
@@ -10,6 +12,7 @@ export const filters = StrictDict({
|
||||
courseGrade: 'courseGrade',
|
||||
courseGradeMax: 'courseGradeMax',
|
||||
courseGradeMin: 'courseGradeMin',
|
||||
excludedCourseRoles: 'excludedCourseRoles',
|
||||
includeCourseRoleMembers: 'includeCourseRoleMembers',
|
||||
track: 'track',
|
||||
});
|
||||
@@ -28,34 +31,34 @@ const initialFilters = {
|
||||
|
||||
export const filterConfig = StrictDict({
|
||||
[filters.assignment]: {
|
||||
displayName: 'Assignment',
|
||||
displayName: messages[filters.assignment],
|
||||
connectedFilters: ['assignment', 'assignmentGradeMax', 'assignmentGradeMax'],
|
||||
},
|
||||
[filters.assignmentType]: {
|
||||
displayName: 'Assignment Type',
|
||||
displayName: messages[filters.assignmentType],
|
||||
connectedFilters: ['assignmentType'],
|
||||
},
|
||||
[filters.assignmentGrade]: {
|
||||
displayName: 'Assignment Grade',
|
||||
filterOrder: ['courseGradeMin', 'courseGradeMax'],
|
||||
connectedFilters: ['courseGradeMax', 'courseGradeMin'],
|
||||
displayName: messages[filters.assignmentGrade],
|
||||
filterOrder: ['assignmentGradeMin', 'assignmentGradeMax'],
|
||||
connectedFilters: ['assignmentGradeMax', 'assignmentGradeMin'],
|
||||
},
|
||||
[filters.cohort]: {
|
||||
displayName: 'Cohort',
|
||||
displayName: messages[filters.cohort],
|
||||
connectedFilters: ['cohort'],
|
||||
},
|
||||
[filters.courseGrade]: {
|
||||
displayName: 'Course Grade',
|
||||
displayName: messages[filters.courseGrade],
|
||||
filterOrder: ['courseGradeMin', 'courseGradeMax'],
|
||||
connectedFilters: ['courseGradeMax', 'courseGradeMin'],
|
||||
},
|
||||
[filters.includeCourseRoleMembers]: {
|
||||
displayName: 'Includeing Course Team Members',
|
||||
displayName: messages[filters.includeCourseRoleMembers],
|
||||
connectedFilters: ['includeCourseRoleMembers'],
|
||||
hideValue: true,
|
||||
},
|
||||
[filters.track]: {
|
||||
displayName: 'Track',
|
||||
displayName: messages[filters.track],
|
||||
connectedFilters: ['track'],
|
||||
},
|
||||
});
|
||||
|
||||
41
src/data/constants/filters.messages.js
Normal file
41
src/data/constants/filters.messages.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||
|
||||
const messages = defineMessages({
|
||||
assignment: {
|
||||
id: 'gradebook.GradesTab.FilterBadges.assignment',
|
||||
defaultMessage: 'Assignment',
|
||||
description: 'Assignment FilterBadge label',
|
||||
},
|
||||
assignmentGrade: {
|
||||
id: 'gradebook.GradesTab.FilterBadges.assignmentGrade',
|
||||
defaultMessage: 'Assignment Grade',
|
||||
description: 'Assignment Grade FilterBadge label',
|
||||
},
|
||||
assignmentType: {
|
||||
id: 'gradebook.GradesTab.FilterBadges.assignmentType',
|
||||
defaultMessage: 'Assignment Type',
|
||||
description: 'Assignment Type FilterBadge label',
|
||||
},
|
||||
cohort: {
|
||||
id: 'gradebook.GradesTab.FilterBadges.cohort',
|
||||
defaultMessage: 'Cohort',
|
||||
description: 'Cohort FilterBadge label',
|
||||
},
|
||||
courseGrade: {
|
||||
id: 'gradebook.GradesTab.FilterBadges.courseGrade',
|
||||
defaultMessage: 'Course Grade',
|
||||
description: 'Course Grade FilterBadge label',
|
||||
},
|
||||
includeCourseRoleMembers: {
|
||||
id: 'gradebook.GradesTab.FilterBadges.includeCourseRoleMembers',
|
||||
defaultMessage: 'Include Course Team Members',
|
||||
description: 'Include Course Team Members FilterBadge label',
|
||||
},
|
||||
track: {
|
||||
id: 'gradebook.GradesTab.FilterBadges.track',
|
||||
defaultMessage: 'Track',
|
||||
description: 'Track FilterBadge label',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -42,6 +42,37 @@ describe('app reducer', () => {
|
||||
).toEqual({ ...testingState, courseId: testValue });
|
||||
});
|
||||
});
|
||||
describe('appActions.filterMenu.startTransition', () => {
|
||||
it('sets filterMenu.transitioning to true', () => {
|
||||
expect(
|
||||
app(testingState, appActions.filterMenu.startTransition()),
|
||||
).toEqual({
|
||||
...testingState,
|
||||
filterMenu: { ...testingState.filterMenu, transitioning: true },
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('appActions.filterMenu.endTransition', () => {
|
||||
it('sets filterMenu.transitioning to false', () => {
|
||||
const transitioningState = {
|
||||
...testingState,
|
||||
filterMenu: { ...testingState.filterMenu, transitioning: true },
|
||||
};
|
||||
expect(
|
||||
app(transitioningState, appActions.filterMenu.endTransition()),
|
||||
).toEqual(testingState);
|
||||
});
|
||||
});
|
||||
describe('appActions.filterMenu.toggle', () => {
|
||||
it('toggles filterMenu.open', () => {
|
||||
const openState = {
|
||||
...testingState,
|
||||
filterMenu: { ...testingState.filterMenu, open: true },
|
||||
};
|
||||
expect(app(testingState, appActions.filterMenu.toggle())).toEqual(openState);
|
||||
expect(app(openState, appActions.filterMenu.toggle())).toEqual(testingState);
|
||||
});
|
||||
});
|
||||
describe('appActions.setLocalFilter', () => {
|
||||
it('loads filter values from the payload', () => {
|
||||
expect(
|
||||
|
||||
@@ -30,17 +30,13 @@ const reducer = (state = initialState, { type: actionType, payload }) => {
|
||||
assignmentGradeMax: payload.assignmentGradeMax,
|
||||
assignmentGradeMin: payload.assignmentGradeMin,
|
||||
};
|
||||
case actions.update.assignmentType.toString():
|
||||
return {
|
||||
...state,
|
||||
assignmentType: payload,
|
||||
assignment: (
|
||||
(
|
||||
payload !== ''
|
||||
&& (state.assignment || {}).type !== payload
|
||||
) ? '' : state.assignment
|
||||
),
|
||||
};
|
||||
case actions.update.assignmentType.toString(): {
|
||||
const newState = { ...state, assignmentType: payload };
|
||||
if (payload !== '' && state.assignment && payload !== state.assignment.type) {
|
||||
newState.assignment = '';
|
||||
}
|
||||
return newState;
|
||||
}
|
||||
case actions.update.cohort.toString():
|
||||
return { ...state, cohort: payload };
|
||||
case actions.update.courseGradeLimits.toString():
|
||||
|
||||
@@ -9,6 +9,7 @@ import grades from './grades';
|
||||
import roles from './roles';
|
||||
import tracks from './tracks';
|
||||
|
||||
/* istanbul ignore next */
|
||||
const rootReducer = combineReducers({
|
||||
app,
|
||||
assignmentTypes,
|
||||
|
||||
@@ -132,6 +132,16 @@ export const selectedAssignmentId = (state) => (simpleSelectors.assignment(state
|
||||
*/
|
||||
export const selectedAssignmentLabel = (state) => (simpleSelectors.assignment(state) || {}).label;
|
||||
|
||||
/**
|
||||
* Returns the api value for excludedCourseRoles based on the
|
||||
* internal Bool value for includeCourseRoleMembers.
|
||||
* @param {object} state - redux state
|
||||
* @return {string} - '' if to be included, else 'all'
|
||||
*/
|
||||
export const excludedCourseRoles = (state) => (
|
||||
simpleSelectors.includeCourseRoleMembers(state) ? '' : 'all'
|
||||
);
|
||||
|
||||
export default StrictDict({
|
||||
...simpleSelectors,
|
||||
isDefault,
|
||||
@@ -143,5 +153,6 @@ export default StrictDict({
|
||||
allFilters,
|
||||
areAssignmentGradeFiltersSet,
|
||||
chooseRelevantAssignmentData,
|
||||
excludedCourseRoles,
|
||||
getAssignmentsFromResultsSubstate,
|
||||
});
|
||||
|
||||
@@ -139,6 +139,15 @@ describe('filters selectors', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('excludedCourseRoles', () => {
|
||||
it('returns empty string if includeCourseRoleMembers', () => {
|
||||
expect(selectors.excludedCourseRoles({ filters: { includeCourseRoleMembers: true } })).toEqual('');
|
||||
});
|
||||
it('returns "all" string if not includeCourseRoleMembers', () => {
|
||||
expect(selectors.excludedCourseRoles({ filters: { includeCourseRoleMembers: false } })).toEqual('all');
|
||||
});
|
||||
});
|
||||
|
||||
describe('selectedAssignmentId', () => {
|
||||
it('gets filtered assignment ID when available', () => {
|
||||
const assignmentId = selectors.selectedAssignmentId(testState);
|
||||
|
||||
@@ -105,11 +105,11 @@ export const headingMapper = (category, label = 'All') => {
|
||||
filter = filters.byLabel;
|
||||
}
|
||||
const { username, email, totalGrade } = Headings;
|
||||
const fillerLabels = (entry) => entry.filter(filter).map(s => s.label);
|
||||
const filteredLabels = (entry) => entry.filter(filter).map(s => s.label);
|
||||
|
||||
return (entry) => (
|
||||
entry
|
||||
? [username, email, ...fillerLabels(entry), totalGrade]
|
||||
? [username, email, ...filteredLabels(entry), totalGrade]
|
||||
: []
|
||||
);
|
||||
};
|
||||
@@ -133,7 +133,6 @@ export const transformHistoryEntry = ({
|
||||
originalFilename,
|
||||
resultsSummary: {
|
||||
rowId: id,
|
||||
courseId,
|
||||
text: module.getRowsProcessed(data),
|
||||
},
|
||||
...rest,
|
||||
@@ -188,7 +187,7 @@ export const allGrades = ({ grades: { results } }) => results;
|
||||
*/
|
||||
export const bulkImportError = ({ grades: { bulkManagement } }) => (
|
||||
(!!bulkManagement && bulkManagement.errorMessages)
|
||||
? `Errors while processing: ${bulkManagement.errorMessages.join(', ')}`
|
||||
? `Errors while processing: ${bulkManagement.errorMessages.join('; ')};`
|
||||
: ''
|
||||
);
|
||||
|
||||
|
||||
@@ -87,6 +87,44 @@ describe('grades selectors', () => {
|
||||
describe('grade formatters', () => {
|
||||
const selectedAssignment = { assignmentId: 'block-v1:edX+type@sequential+block@abcde' };
|
||||
|
||||
describe('formatGradeOverrideForDisplay', () => {
|
||||
it('maps history entries with formatted date, grader, reason, and adjusted grade', () => {
|
||||
const historyArray = [
|
||||
{
|
||||
history_date: 'Jan 01 2021',
|
||||
history_user: 'Grog',
|
||||
override_reason: 'rage',
|
||||
earned_graded_override: 0,
|
||||
},
|
||||
{
|
||||
history_date: 'Jan 02 2021',
|
||||
history_user: 'Keyleth',
|
||||
override_reason: 'nature',
|
||||
earned_graded_override: 10,
|
||||
},
|
||||
{
|
||||
history_date: 'Jan 03 2021',
|
||||
history_user: 'Pike',
|
||||
override_reason: 'Sarenrae',
|
||||
earned_graded_override: 9001,
|
||||
},
|
||||
];
|
||||
const mapped = selectors.formatGradeOverrideForDisplay(historyArray);
|
||||
const testEntry = (index) => {
|
||||
const entry = historyArray[index];
|
||||
expect(mapped[index]).toEqual({
|
||||
date: formatDateForDisplay(new Date(entry.history_date)),
|
||||
grader: entry.history_user,
|
||||
reason: entry.override_reason,
|
||||
adjustedGrade: entry.earned_graded_override,
|
||||
});
|
||||
};
|
||||
testEntry(0);
|
||||
testEntry(1);
|
||||
testEntry(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatMinAssignmentGrade', () => {
|
||||
const modifiedGrade = '1';
|
||||
const selector = selectors.formatMinAssignmentGrade;
|
||||
@@ -200,7 +238,6 @@ describe('grades selectors', () => {
|
||||
it('summarizes processed rows', () => {
|
||||
expect(output.resultsSummary).toEqual({
|
||||
text: selectors.getRowsProcessed(rawEntry.data),
|
||||
courseId: rawEntry.unique_id,
|
||||
rowId: rawEntry.id,
|
||||
});
|
||||
});
|
||||
@@ -276,7 +313,7 @@ describe('grades selectors', () => {
|
||||
expect(
|
||||
selectors.bulkImportError({ grades: { bulkManagement: { errorMessages } } }),
|
||||
).toEqual(
|
||||
`Errors while processing: ${errorMessages[0]}, ${errorMessages[1]}`,
|
||||
`Errors while processing: ${errorMessages[0]}; ${errorMessages[1]};`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user