diff --git a/package-lock.json b/package-lock.json index ba1be8746..5592d527f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,9 +10,10 @@ "license": "AGPL-3.0", "dependencies": { "@edx/brand": "npm:@edx/brand-openedx@1.1.0", - "@edx/frontend-component-footer": "12.0.0", + "@edx/frontend-component-footer": "^12.3.0", + "@edx/frontend-component-header": "^4.7.0", "@edx/frontend-enterprise-hotjar": "^1.2.1", - "@edx/frontend-lib-content-components": "^1.173.4", + "@edx/frontend-lib-content-components": "^1.174.0", "@edx/frontend-platform": "4.2.0", "@edx/paragon": "^20.45.4", "@fortawesome/fontawesome-svg-core": "1.2.28", @@ -2201,69 +2202,142 @@ } }, "node_modules/@edx/frontend-component-footer": { - "version": "12.0.0", - "license": "AGPL-3.0", + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/@edx/frontend-component-footer/-/frontend-component-footer-12.3.0.tgz", + "integrity": "sha512-ivCtioyP4SceYM4/ugVtif4c41Y+epA0NM7sSB/x6s9A/RTQXb2TY3fDc9lB3ah/0+pRwGVJJEVYkPAZ4JdC/g==", "dependencies": { - "@fortawesome/fontawesome-svg-core": "6.4.0", - "@fortawesome/free-brands-svg-icons": "6.4.0", - "@fortawesome/free-regular-svg-icons": "6.4.0", - "@fortawesome/free-solid-svg-icons": "6.4.0", - "@fortawesome/react-fontawesome": "0.2.0" + "@edx/paragon": "^21.3.1", + "@fortawesome/fontawesome-svg-core": "6.4.2", + "@fortawesome/free-brands-svg-icons": "6.4.2", + "@fortawesome/free-regular-svg-icons": "6.4.2", + "@fortawesome/free-solid-svg-icons": "6.4.2", + "@fortawesome/react-fontawesome": "0.2.0", + "lodash": "^4.17.21" }, "peerDependencies": { - "@edx/frontend-platform": "^4.0.0", + "@edx/frontend-platform": "^4.0.0 || ^5.0.0", "prop-types": "^15.5.10", "react": "^16.9.0 || ^17.0.0", "react-dom": "^16.9.0 || ^17.0.0" } }, + "node_modules/@edx/frontend-component-footer/node_modules/@edx/paragon": { + "version": "21.3.1", + "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-21.3.1.tgz", + "integrity": "sha512-bXTUaOEmT8XLnDQzYS8QLMvWK5K2BN4jHlx25lO8N0XWRQeDiQTdbx8OrEbv8QOPTlrv0an5MZc+qjlleJFObg==", + "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.1.1", + "@fortawesome/react-fontawesome": "^0.1.18", + "@popperjs/core": "^2.11.4", + "bootstrap": "^4.6.2", + "chalk": "^4.1.2", + "child_process": "^1.0.2", + "classnames": "^2.3.1", + "email-prop-type": "^3.0.0", + "file-selector": "^0.6.0", + "font-awesome": "^4.7.0", + "glob": "^8.0.3", + "inquirer": "^8.2.5", + "lodash.uniqby": "^4.7.0", + "mailto-link": "^2.0.0", + "prop-types": "^15.8.1", + "react-bootstrap": "^1.6.5", + "react-colorful": "^5.6.1", + "react-dropzone": "^14.2.1", + "react-focus-on": "^3.5.4", + "react-loading-skeleton": "^3.1.0", + "react-popper": "^2.2.5", + "react-proptype-conditional-require": "^1.0.4", + "react-responsive": "^8.2.0", + "react-table": "^7.7.0", + "react-transition-group": "^4.4.2", + "tabbable": "^5.3.3", + "uncontrollable": "^7.2.1", + "uuid": "^9.0.0" + }, + "bin": { + "paragon": "bin/paragon-scripts.js" + }, + "peerDependencies": { + "react": "^16.8.6 || ^17.0.0", + "react-dom": "^16.8.6 || ^17.0.0", + "react-intl": "^5.25.1 || ^6.4.0" + } + }, + "node_modules/@edx/frontend-component-footer/node_modules/@edx/paragon/node_modules/@fortawesome/react-fontawesome": { + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.19.tgz", + "integrity": "sha512-Hyb+lB8T18cvLNX0S3llz7PcSOAJMLwiVKBuuzwM/nI5uoBw+gQjnf9il0fR1C3DKOI5Kc79pkJ4/xB0Uw9aFQ==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.x" + } + }, + "node_modules/@edx/frontend-component-footer/node_modules/@edx/paragon/node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/fontawesome-common-types": { - "version": "6.4.0", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.2.tgz", + "integrity": "sha512-1DgP7f+XQIJbLFCTX1V2QnxVmpLdKdzzo2k8EmvDOePfchaIGQ9eCHj2up3/jNEbZuBqel5OxiaOJf37TWauRA==", "hasInstallScript": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/fontawesome-svg-core": { - "version": "6.4.0", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.2.tgz", + "integrity": "sha512-gjYDSKv3TrM2sLTOKBc5rH9ckje8Wrwgx1CxAPbN5N3Fm4prfi7NsJVWd1jklp7i5uSCVwhZS5qlhMXqLrpAIg==", "hasInstallScript": true, - "license": "MIT", "dependencies": { - "@fortawesome/fontawesome-common-types": "6.4.0" + "@fortawesome/fontawesome-common-types": "6.4.2" }, "engines": { "node": ">=6" } }, "node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/free-brands-svg-icons": { - "version": "6.4.0", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.4.2.tgz", + "integrity": "sha512-LKOwJX0I7+mR/cvvf6qIiqcERbdnY+24zgpUSouySml+5w8B4BJOx8EhDR/FTKAu06W12fmUIcv6lzPSwYKGGg==", "hasInstallScript": true, - "license": "(CC-BY-4.0 AND MIT)", "dependencies": { - "@fortawesome/fontawesome-common-types": "6.4.0" + "@fortawesome/fontawesome-common-types": "6.4.2" }, "engines": { "node": ">=6" } }, "node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/free-regular-svg-icons": { - "version": "6.4.0", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.4.2.tgz", + "integrity": "sha512-0+sIUWnkgTVVXVAPQmW4vxb9ZTHv0WstOa3rBx9iPxrrrDH6bNLsDYuwXF9b6fGm+iR7DKQvQshUH/FJm3ed9Q==", "hasInstallScript": true, - "license": "(CC-BY-4.0 AND MIT)", "dependencies": { - "@fortawesome/fontawesome-common-types": "6.4.0" + "@fortawesome/fontawesome-common-types": "6.4.2" }, "engines": { "node": ">=6" } }, "node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/free-solid-svg-icons": { - "version": "6.4.0", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.2.tgz", + "integrity": "sha512-sYwXurXUEQS32fZz9hVCUUv/xu49PEJEyUOsA51l6PU/qVgfbTb2glsTEaJngVVT8VqBATRIdh7XVgV1JF1LkA==", "hasInstallScript": true, - "license": "(CC-BY-4.0 AND MIT)", "dependencies": { - "@fortawesome/fontawesome-common-types": "6.4.0" + "@fortawesome/fontawesome-common-types": "6.4.2" }, "engines": { "node": ">=6" @@ -2289,6 +2363,485 @@ "react-is": "^16.13.1" } }, + "node_modules/@edx/frontend-component-footer/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@edx/frontend-component-footer/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@edx/frontend-component-footer/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@edx/frontend-component-footer/node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, + "node_modules/@edx/frontend-component-footer/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@edx/frontend-component-footer/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@edx/frontend-component-footer/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@edx/frontend-component-footer/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@edx/frontend-component-footer/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@edx/frontend-component-footer/node_modules/react-responsive": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-8.2.0.tgz", + "integrity": "sha512-iagCqVrw4QSjhxKp3I/YK6+ODkWY6G+YPElvdYKiUUbywwh9Ds0M7r26Fj2/7dWFFbOpcGnJE6uE7aMck8j5Qg==", + "dependencies": { + "hyphenate-style-name": "^1.0.0", + "matchmediaquery": "^0.3.0", + "prop-types": "^15.6.1", + "shallow-equal": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@edx/frontend-component-footer/node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/@edx/frontend-component-footer/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@edx/frontend-component-footer/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@edx/frontend-component-header": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@edx/frontend-component-header/-/frontend-component-header-4.7.0.tgz", + "integrity": "sha512-hJCWfdEed8h7aRKmo5lCMyemtMR272q/g1WOetMy8C8ZzeNvf8t94WPFCK4OlbHWTQBd5UiaqGWQWmaGXm0jVg==", + "dependencies": { + "@edx/paragon": "21.1.10", + "@fortawesome/fontawesome-svg-core": "6.4.2", + "@fortawesome/free-brands-svg-icons": "6.4.2", + "@fortawesome/free-regular-svg-icons": "6.4.2", + "@fortawesome/free-solid-svg-icons": "6.4.2", + "@fortawesome/react-fontawesome": "^0.2.0", + "axios-mock-adapter": "1.21.5", + "babel-polyfill": "6.26.0", + "react-responsive": "8.2.0", + "react-transition-group": "4.4.5" + }, + "peerDependencies": { + "@edx/frontend-platform": "^4.0.0 || ^5.0.0", + "prop-types": "^15.5.10", + "react": "^16.9.0 || ^17.0.0", + "react-dom": "^16.9.0 || ^17.0.0" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/@edx/paragon": { + "version": "21.1.10", + "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-21.1.10.tgz", + "integrity": "sha512-5U8tUaL20gDiKfEDr/tuRXrl7fJsN+KgAIn5bWkTtS5Us7r+H+m3LkD58HY7Ntwj8bCrSEtW7YuK3PMabXcMRA==", + "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.1.1", + "@fortawesome/react-fontawesome": "^0.1.18", + "@popperjs/core": "^2.11.4", + "bootstrap": "^4.6.2", + "chalk": "^4.1.2", + "child_process": "^1.0.2", + "classnames": "^2.3.1", + "email-prop-type": "^3.0.0", + "file-selector": "^0.6.0", + "font-awesome": "^4.7.0", + "glob": "^8.0.3", + "inquirer": "^8.2.5", + "lodash.uniqby": "^4.7.0", + "mailto-link": "^2.0.0", + "prop-types": "^15.8.1", + "react-bootstrap": "^1.6.5", + "react-colorful": "^5.6.1", + "react-dropzone": "^14.2.1", + "react-focus-on": "^3.5.4", + "react-loading-skeleton": "^3.1.0", + "react-popper": "^2.2.5", + "react-proptype-conditional-require": "^1.0.4", + "react-responsive": "^8.2.0", + "react-table": "^7.7.0", + "react-transition-group": "^4.4.2", + "tabbable": "^5.3.3", + "uncontrollable": "^7.2.1", + "uuid": "^9.0.0" + }, + "bin": { + "paragon": "bin/paragon-scripts.js" + }, + "peerDependencies": { + "react": "^16.8.6 || ^17.0.0", + "react-dom": "^16.8.6 || ^17.0.0", + "react-intl": "^5.25.1 || ^6.4.0" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/@edx/paragon/node_modules/@fortawesome/react-fontawesome": { + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.19.tgz", + "integrity": "sha512-Hyb+lB8T18cvLNX0S3llz7PcSOAJMLwiVKBuuzwM/nI5uoBw+gQjnf9il0fR1C3DKOI5Kc79pkJ4/xB0Uw9aFQ==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.x" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/@edx/paragon/node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.2.tgz", + "integrity": "sha512-1DgP7f+XQIJbLFCTX1V2QnxVmpLdKdzzo2k8EmvDOePfchaIGQ9eCHj2up3/jNEbZuBqel5OxiaOJf37TWauRA==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.2.tgz", + "integrity": "sha512-gjYDSKv3TrM2sLTOKBc5rH9ckje8Wrwgx1CxAPbN5N3Fm4prfi7NsJVWd1jklp7i5uSCVwhZS5qlhMXqLrpAIg==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.4.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/free-brands-svg-icons": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.4.2.tgz", + "integrity": "sha512-LKOwJX0I7+mR/cvvf6qIiqcERbdnY+24zgpUSouySml+5w8B4BJOx8EhDR/FTKAu06W12fmUIcv6lzPSwYKGGg==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.4.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/free-regular-svg-icons": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.4.2.tgz", + "integrity": "sha512-0+sIUWnkgTVVXVAPQmW4vxb9ZTHv0WstOa3rBx9iPxrrrDH6bNLsDYuwXF9b6fGm+iR7DKQvQshUH/FJm3ed9Q==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.4.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.2.tgz", + "integrity": "sha512-sYwXurXUEQS32fZz9hVCUUv/xu49PEJEyUOsA51l6PU/qVgfbTb2glsTEaJngVVT8VqBATRIdh7XVgV1JF1LkA==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.4.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz", + "integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/react-fontawesome/node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/axios-mock-adapter": { + "version": "1.21.5", + "resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.21.5.tgz", + "integrity": "sha512-5NI1V/VK+8+JeTF8niqOowuysA4b8mGzdlMN/QnTnoXbYh4HZSNiopsDclN2g/m85+G++IrEtUdZaQ3GnaMsSA==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "is-buffer": "^2.0.5" + }, + "peerDependencies": { + "axios": ">= 0.17.0" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, + "node_modules/@edx/frontend-component-header/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@edx/frontend-component-header/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/react-responsive": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-8.2.0.tgz", + "integrity": "sha512-iagCqVrw4QSjhxKp3I/YK6+ODkWY6G+YPElvdYKiUUbywwh9Ds0M7r26Fj2/7dWFFbOpcGnJE6uE7aMck8j5Qg==", + "dependencies": { + "hyphenate-style-name": "^1.0.0", + "matchmediaquery": "^0.3.0", + "prop-types": "^15.6.1", + "shallow-equal": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@edx/frontend-enterprise-hotjar": { "version": "1.2.1", "license": "AGPL-3.0", @@ -2299,9 +2852,9 @@ } }, "node_modules/@edx/frontend-lib-content-components": { - "version": "1.173.4", - "resolved": "https://registry.npmjs.org/@edx/frontend-lib-content-components/-/frontend-lib-content-components-1.173.4.tgz", - "integrity": "sha512-yYHwBAxyshHyMr6t9ikH4gX0vXaee+qjwSIfHEZkgYzQLRRgCHPi0Iigzvz5pPEepvtlooVWEz17wkzz6nZqXg==", + "version": "1.174.0", + "resolved": "https://registry.npmjs.org/@edx/frontend-lib-content-components/-/frontend-lib-content-components-1.174.0.tgz", + "integrity": "sha512-Vwf9XHEYZ4yA9J40AsIfCgn6rF/SPBual2P3/FoniRy2MazfXALA7ikAAWaoGdn0RGfgY51TaTcum4A4ImE0uw==", "dependencies": { "@codemirror/lang-html": "^6.0.0", "@codemirror/lang-xml": "^6.0.0", @@ -2537,9 +3090,9 @@ } }, "node_modules/@edx/paragon": { - "version": "20.45.4", - "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.45.4.tgz", - "integrity": "sha512-ifkkBR4PRGlsFdMwuyYznUMrifyaO9Yy0PyTsP2iD99Pn5ZZMqYOmtvMm8Ek087ABbc/7MIwzxWXMhTvQpNVNw==", + "version": "20.46.2", + "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.46.2.tgz", + "integrity": "sha512-px+KS/BV1CbiMKgfVgUofyjJi4CHUCUOLRukJbT66VPPqWP4Xon5Rns6uohoratPXMg2kNN46v2L8wIwqKQ4Lw==", "dependencies": { "@fortawesome/fontawesome-svg-core": "^6.1.1", "@fortawesome/react-fontawesome": "^0.1.18", @@ -5514,7 +6067,6 @@ }, "node_modules/ansi-escapes": { "version": "4.3.2", - "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.21.3" @@ -5539,7 +6091,6 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5916,7 +6467,6 @@ }, "node_modules/axios": { "version": "0.21.4", - "dev": true, "license": "MIT", "dependencies": { "follow-redirects": "^1.14.0" @@ -6324,7 +6874,6 @@ }, "node_modules/base64-js": { "version": "1.5.1", - "dev": true, "funding": [ { "type": "github", @@ -6364,7 +6913,6 @@ }, "node_modules/bl": { "version": "4.1.0", - "dev": true, "license": "MIT", "dependencies": { "buffer": "^5.5.0", @@ -6374,7 +6922,6 @@ }, "node_modules/bl/node_modules/readable-stream": { "version": "3.6.2", - "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -6549,7 +7096,6 @@ }, "node_modules/buffer": { "version": "5.7.1", - "dev": true, "funding": [ { "type": "github", @@ -6787,6 +7333,11 @@ "node": ">=10" } }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, "node_modules/cheerio": { "version": "1.0.0-rc.12", "dev": true, @@ -6823,6 +7374,11 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/child_process": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz", + "integrity": "sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g==" + }, "node_modules/chokidar": { "version": "3.5.3", "dev": true, @@ -7010,6 +7566,36 @@ "webpack": "*" } }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.1.tgz", + "integrity": "sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "engines": { + "node": ">= 10" + } + }, "node_modules/cliui": { "version": "7.0.4", "dev": true, @@ -7020,6 +7606,14 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/clone-deep": { "version": "4.0.1", "dev": true, @@ -7908,6 +8502,17 @@ "node": ">= 8" } }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/define-lazy-prop": { "version": "2.0.0", "dev": true, @@ -8587,7 +9192,6 @@ }, "node_modules/escape-string-regexp": { "version": "1.0.5", - "dev": true, "license": "MIT", "engines": { "node": ">=0.8.0" @@ -9739,6 +10343,30 @@ "node": ">=0.10.0" } }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/external-editor/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/extglob": { "version": "2.0.4", "dev": true, @@ -9789,7 +10417,6 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "dev": true, "license": "MIT" }, "node_modules/fast-defer": { @@ -9856,6 +10483,20 @@ "bser": "2.1.1" } }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "dev": true, @@ -11257,7 +11898,6 @@ }, "node_modules/ieee754": { "version": "1.2.1", - "dev": true, "funding": [ { "type": "github", @@ -11464,6 +12104,108 @@ "dev": true, "license": "ISC" }, + "node_modules/inquirer": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/inquirer/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/inquirer/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/inquirer/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/inquirer/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/inquirer/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/internal-slot": { "version": "1.0.5", "dev": true, @@ -11597,7 +12339,6 @@ }, "node_modules/is-buffer": { "version": "2.0.5", - "dev": true, "funding": [ { "type": "github", @@ -11731,7 +12472,6 @@ }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11760,6 +12500,14 @@ "node": ">=0.10.0" } }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-invalid-path": { "version": "0.1.0", "dev": true, @@ -11986,6 +12734,17 @@ "dev": true, "license": "MIT" }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-valid-path": { "version": "0.1.1", "dev": true, @@ -14680,6 +15439,85 @@ "version": "4.7.0", "license": "MIT" }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "license": "MIT", @@ -15011,7 +15849,6 @@ }, "node_modules/mimic-fn": { "version": "2.1.0", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -15226,6 +16063,11 @@ "multicast-dns": "cli.js" } }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, "node_modules/mux.js": { "version": "6.0.1", "license": "Apache-2.0", @@ -15890,7 +16732,6 @@ }, "node_modules/onetime": { "version": "5.1.2", - "dev": true, "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" @@ -15950,6 +16791,100 @@ "node": ">= 0.8.0" } }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ora/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/ora/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/p-each-series": { "version": "2.2.0", "dev": true, @@ -18668,6 +19603,18 @@ "node": ">=0.10.0" } }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ret": { "version": "0.1.15", "dev": true, @@ -18735,6 +19682,14 @@ "rtlcss": "bin/rtlcss.js" } }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/run-node": { "version": "1.0.0", "dev": true, @@ -18775,6 +19730,14 @@ "individual": "^2.0.0" } }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "license": "MIT" @@ -18808,7 +19771,6 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "dev": true, "license": "MIT" }, "node_modules/sane": { @@ -19417,7 +20379,6 @@ }, "node_modules/signal-exit": { "version": "3.0.7", - "dev": true, "license": "ISC" }, "node_modules/simple-concat": { @@ -20101,7 +21062,6 @@ }, "node_modules/string-width": { "version": "4.2.3", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -20114,7 +21074,6 @@ }, "node_modules/string-width/node_modules/emoji-regex": { "version": "8.0.0", - "dev": true, "license": "MIT" }, "node_modules/string.prototype.matchall": { @@ -20179,7 +21138,6 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -20927,6 +21885,11 @@ "dev": true, "license": "MIT" }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, "node_modules/thunky": { "version": "1.1.0", "dev": true, @@ -20944,6 +21907,17 @@ "version": "5.10.5", "license": "LGPL-2.1" }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/tmpl": { "version": "1.0.5", "dev": true, @@ -21137,7 +22111,6 @@ }, "node_modules/type-fest": { "version": "0.21.3", - "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -21677,6 +22650,14 @@ "minimalistic-assert": "^1.0.0" } }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dependencies": { + "defaults": "^1.0.3" + } + }, "node_modules/webidl-conversions": { "version": "6.1.0", "dev": true, diff --git a/package.json b/package.json index ab5ef3524..36fd33d3d 100644 --- a/package.json +++ b/package.json @@ -35,9 +35,10 @@ }, "dependencies": { "@edx/brand": "npm:@edx/brand-openedx@1.1.0", - "@edx/frontend-component-footer": "12.0.0", + "@edx/frontend-component-footer": "^12.3.0", + "@edx/frontend-component-header": "^4.7.0", "@edx/frontend-enterprise-hotjar": "^1.2.1", - "@edx/frontend-lib-content-components": "^1.173.4", + "@edx/frontend-lib-content-components": "^1.174.0", "@edx/frontend-platform": "4.2.0", "@edx/paragon": "^20.45.4", "@fortawesome/fontawesome-svg-core": "1.2.28", diff --git a/src/AppFooter.jsx b/src/AppFooter.jsx deleted file mode 100644 index 6cb9eb4f1..000000000 --- a/src/AppFooter.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Footer } from '@edx/frontend-lib-content-components'; - -const AppFooter = () => ( -
-
-); - -export default AppFooter; diff --git a/src/AppFooter.test.jsx b/src/AppFooter.test.jsx deleted file mode 100644 index b6a3fa253..000000000 --- a/src/AppFooter.test.jsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -import { render } from '@testing-library/react'; -import { IntlProvider } from '@edx/frontend-platform/i18n'; -import AppFooter from './AppFooter'; - -describe('', () => { - const RootWrapper = () => ( - - - - ); - it('should render the footer successfully', () => { - const { getByText } = render(); - expect(getByText('Looking for help with Studio?')).toBeInTheDocument(); - expect(getByText('LMS')).toHaveAttribute('href', process.env.LMS_BASE_URL); - }); -}); diff --git a/src/CourseAuthoringPage.jsx b/src/CourseAuthoringPage.jsx index 3c9688c52..b11dcc794 100644 --- a/src/CourseAuthoringPage.jsx +++ b/src/CourseAuthoringPage.jsx @@ -5,14 +5,14 @@ import { useDispatch, useSelector } from 'react-redux'; import { useLocation, } from 'react-router-dom'; -import Header from './studio-header/Header'; +import { StudioFooter } from '@edx/frontend-component-footer'; +import Header from './header'; import { fetchCourseDetail } from './data/thunks'; import { useModel } from './generic/model-store'; import PermissionDeniedAlert from './generic/PermissionDeniedAlert'; import { getCourseAppsApiStatus } from './pages-and-resources/data/selectors'; import { RequestStatus } from './data/constants'; import Loading from './generic/Loading'; -import AppFooter from './AppFooter'; const AppHeader = ({ courseNumber, courseOrg, courseTitle, courseId, @@ -76,7 +76,7 @@ const CourseAuthoringPage = ({ courseId, children }) => { ) )} {children} - {!inProgress && showHeader && } + {!inProgress && showHeader && } ); }; diff --git a/src/CourseAuthoringRoutes.test.jsx b/src/CourseAuthoringRoutes.test.jsx index 8e1bd6fd1..8e37abe12 100644 --- a/src/CourseAuthoringRoutes.test.jsx +++ b/src/CourseAuthoringRoutes.test.jsx @@ -65,7 +65,7 @@ describe('', () => { store = initializeStore(); }); - it('renders the PagesAndResources component when the pages and resources route is active', () => { + fit('renders the PagesAndResources component when the pages and resources route is active', () => { render( @@ -74,7 +74,7 @@ describe('', () => { , ); - expect(screen.queryByText(pagesAndResourcesMockText)).toBeInTheDocument(); + expect(screen.getByText(pagesAndResourcesMockText)).toBeVisible(); expect(screen.queryByText(proctoredExamSeetingsMockText)).not.toBeInTheDocument(); expect(mockComponentFn).toHaveBeenCalledWith( expect.objectContaining({ diff --git a/src/course-rerun/index.jsx b/src/course-rerun/index.jsx index 9df8626d6..bffdb8cbb 100644 --- a/src/course-rerun/index.jsx +++ b/src/course-rerun/index.jsx @@ -9,13 +9,13 @@ import { Button, } from '@edx/paragon'; import { history } from '@edx/frontend-platform'; +import { StudioFooter } from '@edx/frontend-component-footer'; -import Header from '../studio-header/Header'; +import Header from '../header'; import Loading from '../generic/Loading'; import { getLoadingStatuses } from '../generic/data/selectors'; import InternetConnectionAlert from '../generic/internet-connection-alert'; import { RequestStatus } from '../data/constants'; -import AppFooter from '../AppFooter'; import CourseRerunForm from './course-rerun-form'; import CourseRerunSideBar from './course-rerun-sidebar'; import messages from './messages'; @@ -87,7 +87,7 @@ const CourseRerun = ({ courseId }) => { isQueryPending={savingStatus === RequestStatus.PENDING} /> - + ); }; diff --git a/src/header/Header.jsx b/src/header/Header.jsx new file mode 100644 index 000000000..2cde27f8c --- /dev/null +++ b/src/header/Header.jsx @@ -0,0 +1,72 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { getConfig } from '@edx/frontend-platform'; +import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; + +import { StudioHeader } from '@edx/frontend-component-header'; +import { getContentMenuItems, getSettingMenuItems, getToolsMenuItems } from './utils'; +import messages from './messages'; + +const Header = ({ + courseId, + courseOrg, + courseNumber, + courseTitle, + isHiddenMainMenu, + // injected + intl, +}) => { + const studioBaseUrl = getConfig().STUDIO_BASE_URL; + const mainMenuDropdowns = [ + { + id: `${intl.formatMessage(messages['header.links.content'])}-dropdown-menu`, + buttonTitle: intl.formatMessage(messages['header.links.content']), + items: getContentMenuItems({ studioBaseUrl, courseId, intl }), + }, + { + id: `${intl.formatMessage(messages['header.links.settings'])}-dropdown-menu`, + buttonTitle: intl.formatMessage(messages['header.links.settings']), + items: getSettingMenuItems({ studioBaseUrl, courseId, intl }), + }, + { + id: `${intl.formatMessage(messages['header.links.tools'])}-dropdown-menu`, + buttonTitle: intl.formatMessage(messages['header.links.tools']), + items: getToolsMenuItems({ studioBaseUrl, courseId, intl }), + }, + ]; + const outlineLink = `${studioBaseUrl}/course/${courseId}`; + return ( +
+ +
+ ); +}; + +Header.propTypes = { + courseId: PropTypes.string, + courseNumber: PropTypes.string, + courseOrg: PropTypes.string, + courseTitle: PropTypes.string, + isHiddenMainMenu: PropTypes.bool, + // injected + intl: intlShape.isRequired, +}; + +Header.defaultProps = { + courseId: '', + courseNumber: '', + courseOrg: '', + courseTitle: '', + isHiddenMainMenu: false, +}; + +export default injectIntl(Header); diff --git a/src/header/header.scss b/src/header/header.scss new file mode 100644 index 000000000..43443641c --- /dev/null +++ b/src/header/header.scss @@ -0,0 +1,65 @@ +// This SCSS was partly copied from edx/frontend-app-support-tools/src/support-header/index.scss. +$spacer: 1rem; +$white: #FFFFFF; + +.btn-tertiary:hover { + color: white; + background-color: #00262B; +} + +.course-title-lockup { + @media only screen and (max-width: 768px) { + padding-left: .5rem; + max-width: 70%; + } + + @media only screen and (min-width: 769px) { + padding: .5rem; + padding-right: $spacer; + border-right: 1px solid #E5E5E5; + min-width: 70%; + } + + overflow: hidden; + + span { + color: #333333; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + line-height: 1.375rem; + } +} + +.site-header-mobile, +.site-header-desktop { + position: relative; + z-index: 1000; +} + +.site-header-mobile { + img { + height: 1.5rem; + } +} + +.site-header-desktop { + height: 3.75rem; + box-shadow: 0 1px 0 0 rgb(0 0 0 / .1); + background: $white; + + .logo { + display: block; + box-sizing: content-box; + position: relative; + top: -.05em; + height: 1.75rem; + padding: $spacer 0; + margin-right: $spacer; + + img { + display: block; + height: 100%; + } + } +} diff --git a/src/header/index.js b/src/header/index.js new file mode 100644 index 000000000..579f1ac23 --- /dev/null +++ b/src/header/index.js @@ -0,0 +1 @@ +export { default } from './Header'; diff --git a/src/studio-header/messages.js b/src/header/messages.js similarity index 100% rename from src/studio-header/messages.js rename to src/header/messages.js diff --git a/src/studio-header/utils.js b/src/header/utils.js similarity index 72% rename from src/studio-header/utils.js rename to src/header/utils.js index 5b5c96361..8bce20f90 100644 --- a/src/studio-header/utils.js +++ b/src/header/utils.js @@ -1,7 +1,7 @@ import { getPagePath } from '../utils'; import messages from './messages'; -export const getContentMenuItem = ({ studioBaseUrl, courseId, intl }) => { +export const getContentMenuItems = ({ studioBaseUrl, courseId, intl }) => { const items = [ { href: `${studioBaseUrl}/course/${courseId}`, @@ -70,36 +70,3 @@ export const getToolsMenuItems = ({ studioBaseUrl, courseId, intl }) => ([ title: intl.formatMessage(messages['header.links.checklists']), }, ]); - -export const getUserMenuItems = ({ - studioBaseUrl, - logoutUrl, - intl, - isAdmin, -}) => { - let items = [ - { - href: `${studioBaseUrl}}`, - title: intl.formatMessage(messages['header.user.menu.studio']), - }, { - href: `${logoutUrl}`, - title: intl.formatMessage(messages['header.user.menu.logout']), - }, - ]; - if (isAdmin) { - items = [ - { - href: `${studioBaseUrl}}`, - title: intl.formatMessage(messages['header.user.menu.studio']), - }, { - href: `${studioBaseUrl}/maintenance`, - title: intl.formatMessage(messages['header.user.menu.maintenance']), - }, { - href: `${logoutUrl}`, - title: intl.formatMessage(messages['header.user.menu.logout']), - }, - ]; - } - - return items; -}; diff --git a/src/header/utils.test.js b/src/header/utils.test.js new file mode 100644 index 000000000..3f7a35ba7 --- /dev/null +++ b/src/header/utils.test.js @@ -0,0 +1,23 @@ +import { getContentMenuItems } from './utils'; + +const props = { + studioBaseUrl: 'UrLSTuiO', + courseId: '123', + intl: { + formatMessage: jest.fn(), + }, +}; + +describe('header utils', () => { + describe('getContentMenuItems', () => { + it('should include Video Uploads option', () => { + const actualItems = getContentMenuItems(props); + expect(actualItems).toHaveLength(5); + }); + it('should not include Video Uploads option', () => { + process.env.ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN = 'false'; + const actualItems = getContentMenuItems(props); + expect(actualItems).toHaveLength(4); + }); + }); +}); diff --git a/src/index.scss b/src/index.scss index 55dea0489..bc0a403f1 100755 --- a/src/index.scss +++ b/src/index.scss @@ -2,8 +2,7 @@ @import "~@edx/brand/paragon/variables"; @import "~@edx/paragon/scss/core/core"; @import "~@edx/brand/paragon/overrides"; -@import "studio-header/header"; -@import "~@edx/frontend-component-footer/dist/footer"; +@import "header/header"; @import "assets/scss/variables"; @import "assets/scss/form"; @import "assets/scss/utilities"; diff --git a/src/studio-header/BrandNav.jsx b/src/studio-header/BrandNav.jsx deleted file mode 100644 index e546922e4..000000000 --- a/src/studio-header/BrandNav.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import PropTypes from 'prop-types'; - -const BrandNav = ({ - studioBaseUrl, - logo, - logoAltText, -}) => ( - - {logoAltText} - -); - -BrandNav.propTypes = { - studioBaseUrl: PropTypes.string.isRequired, - logo: PropTypes.string.isRequired, - logoAltText: PropTypes.string.isRequired, -}; - -export default BrandNav; diff --git a/src/studio-header/CourseLockUp.jsx b/src/studio-header/CourseLockUp.jsx deleted file mode 100644 index 3cf871cf7..000000000 --- a/src/studio-header/CourseLockUp.jsx +++ /dev/null @@ -1,54 +0,0 @@ -import PropTypes from 'prop-types'; -import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; -import { - OverlayTrigger, - Tooltip, -} from '@edx/paragon'; -import { getPagePath } from '../utils'; -import messages from './messages'; - -const CourseLockUp = ({ - courseId, - courseOrg, - courseNumber, - courseTitle, - // injected - intl, -}) => ( - - {courseTitle} - - )} - > - - {courseOrg} {courseNumber} - {courseTitle} - - -); - -CourseLockUp.propTypes = { - courseId: PropTypes.string, - courseNumber: PropTypes.string, - courseOrg: PropTypes.string, - courseTitle: PropTypes.string, - // injected - intl: intlShape.isRequired, -}; - -CourseLockUp.defaultProps = { - courseNumber: null, - courseOrg: null, - courseId: null, - courseTitle: null, -}; - -export default injectIntl(CourseLockUp); diff --git a/src/studio-header/Header.jsx b/src/studio-header/Header.jsx deleted file mode 100644 index 1dbe64b37..000000000 --- a/src/studio-header/Header.jsx +++ /dev/null @@ -1,64 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { useContext } from 'react'; -import Responsive from 'react-responsive'; -import { AppContext } from '@edx/frontend-platform/react'; -import { ensureConfig } from '@edx/frontend-platform'; - -import MobileHeader from './MobileHeader'; -import HeaderBody from './HeaderBody'; - -ensureConfig([ - 'STUDIO_BASE_URL', - 'LOGOUT_URL', - 'LOGIN_URL', - 'LOGO_URL', -], 'Header component'); - -const Header = ({ - courseId, courseNumber, courseOrg, courseTitle, isHiddenMainMenu, -}) => { - const { authenticatedUser, config } = useContext(AppContext); - - const props = { - logo: config.LOGO_URL, - logoAltText: `Studio ${config.SITE_NAME}`, - courseId, - courseNumber, - courseOrg, - courseTitle, - username: authenticatedUser?.username, - isAdmin: authenticatedUser?.administrator, - authenticatedUserAvatar: authenticatedUser?.avatar, - studioBaseUrl: config.STUDIO_BASE_URL, - logoutUrl: config.LOGOUT_URL, - isHiddenMainMenu, - }; - - return ( - <> - - - - - - - - ); -}; - -Header.propTypes = { - courseId: PropTypes.string, - courseNumber: PropTypes.string, - courseOrg: PropTypes.string, - courseTitle: PropTypes.string.isRequired, - isHiddenMainMenu: PropTypes.bool, -}; - -Header.defaultProps = { - courseId: null, - courseNumber: null, - courseOrg: null, - isHiddenMainMenu: false, -}; - -export default Header; diff --git a/src/studio-header/Header.test.jsx b/src/studio-header/Header.test.jsx deleted file mode 100644 index 507f6ab13..000000000 --- a/src/studio-header/Header.test.jsx +++ /dev/null @@ -1,146 +0,0 @@ -import { - render, - fireEvent, - waitFor, -} from '@testing-library/react'; - -import { initializeMockApp } from '@edx/frontend-platform'; -import { AppProvider } from '@edx/frontend-platform/react'; -import { IntlProvider } from '@edx/frontend-platform/i18n'; -import { Context as ResponsiveContext } from 'react-responsive'; - -import initializeStore from '../store'; -import Header from './Header'; -import messages from './messages'; - -let store; - -const RootWrapper = (props) => ( - // eslint-disable-next-line react/jsx-no-constructed-context-values, react/prop-types - - - -
- - - -); - -const props = { - courseId: 'testEd123', - courseNumber: '123', - courseOrg: 'Ed', - courseTitle: 'test', -}; - -describe('Header', () => { - describe('desktop', () => { - beforeEach(async () => { - initializeMockApp({ - authenticatedUser: { - userId: 3, - username: 'abc123', - administrator: false, - roles: [], - }, - }); - store = initializeStore({}); - }); - it('course lock up should be visible', () => { - const { getByTestId } = render(); - const courseLockUpBlock = getByTestId('course-lock-up-block'); - expect(courseLockUpBlock).toBeVisible(); - }); - it('mobile menu should not be visible', () => { - const { queryByTestId } = render(); - const mobileMenuButton = queryByTestId('mobile-menu-button'); - expect(mobileMenuButton).toBeNull(); - }); - it('desktop menu should be visible', () => { - const { getByTestId } = render(); - const desktopMenu = getByTestId('desktop-menu'); - expect(desktopMenu).toBeVisible(); - }); - it('video uploads should be in content menu', async () => { - const { getAllByRole, getByText } = render(); - const contentMenu = getAllByRole('button')[0]; - await waitFor(() => fireEvent.click(contentMenu)); - const videoUploadButton = getByText(messages['header.links.videoUploads'].defaultMessage); - expect(videoUploadButton).toBeVisible(); - }); - it('maintenance should not be in user menu', async () => { - const { getAllByRole, queryByText } = render(); - const userMenu = getAllByRole('button')[3]; - await waitFor(() => fireEvent.click(userMenu)); - const maintenanceButton = queryByText(messages['header.user.menu.maintenance'].defaultMessage); - expect(maintenanceButton).toBeNull(); - }); - it('user menu should use avatar icon', async () => { - const { getByTestId } = render(); - const avatarIcon = getByTestId('avatar-icon'); - expect(avatarIcon).toBeVisible(); - }); - it('should hide nav items if prop isHiddenMainMenu true', async () => { - const initialProps = { ...props, isHiddenMainMenu: true }; - const { queryByTestId } = render(); - const desktopMenu = queryByTestId('desktop-menu'); - const mobileMenuButton = queryByTestId('mobile-menu-button'); - expect(mobileMenuButton).toBeNull(); - expect(desktopMenu).toBeNull(); - }); - }); - describe('mobile', () => { - beforeEach(async () => { - initializeMockApp({ - authenticatedUser: { - userId: 3, - username: 'abc123', - administrator: true, - roles: [], - avatar: '/imges/test.png', - }, - }); - store = initializeStore({}); - }); - it('course lock up should not be visible', async () => { - const { queryByTestId } = render(); - const courseLockUpBlock = queryByTestId('course-lock-up-block'); - expect(courseLockUpBlock).toBeNull(); - }); - it('mobile menu should be visible', async () => { - const { getByTestId } = render(); - const mobileMenuButton = getByTestId('mobile-menu-button'); - expect(mobileMenuButton).toBeVisible(); - await waitFor(() => fireEvent.click(mobileMenuButton)); - const mobileMenu = getByTestId('mobile-menu'); - expect(mobileMenu).toBeVisible(); - }); - it('desktop menu should not be visible', () => { - const { queryByTestId } = render(); - const desktopMenu = queryByTestId('desktop-menu'); - expect(desktopMenu).toBeNull(); - }); - it('maintenance should be in user menu', async () => { - const { getAllByRole, getByText } = render(); - const userMenu = getAllByRole('button')[1]; - await waitFor(() => fireEvent.click(userMenu)); - const maintenanceButton = getByText(messages['header.user.menu.maintenance'].defaultMessage); - expect(maintenanceButton).toBeVisible(); - }); - it('user menu should use avatar image', async () => { - const { getByTestId } = render(); - const avatarImage = getByTestId('avatar-image'); - expect(avatarImage).toBeVisible(); - }); - it('should hide nav items if prop isHiddenMainMenu true', async () => { - const initialProps = { ...props, isHiddenMainMenu: true }; - const { queryByTestId } = render(); - const desktopMenu = queryByTestId('desktop-menu'); - const mobileMenuButton = queryByTestId('mobile-menu-button'); - expect(mobileMenuButton).toBeNull(); - expect(desktopMenu).toBeNull(); - }); - }); -}); diff --git a/src/studio-header/HeaderBody.jsx b/src/studio-header/HeaderBody.jsx deleted file mode 100644 index 75dc8a376..000000000 --- a/src/studio-header/HeaderBody.jsx +++ /dev/null @@ -1,158 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; -import { - ActionRow, - Button, - Nav, - Row, -} from '@edx/paragon'; -import { Close, MenuIcon } from '@edx/paragon/icons'; - -import messages from './messages'; -import CourseLockUp from './CourseLockUp'; -import UserMenu from './UserMenu'; -import BrandNav from './BrandNav'; -import NavDropdownMenu from './NavDropdownMenu'; -import { getContentMenuItem, getSettingMenuItems, getToolsMenuItems } from './utils'; - -const HeaderBody = ({ - logo, - logoAltText, - courseId, - courseNumber, - courseOrg, - courseTitle, - username, - isAdmin, - studioBaseUrl, - logoutUrl, - authenticatedUserAvatar, - isMobile, - setModalPopupTarget, - toggleModalPopup, - isModalPopupOpen, - isHiddenMainMenu, - // injected - intl, -}) => { - const renderBrandNav = ( - - ); - - return ( - - {isHiddenMainMenu ? ( - - {renderBrandNav} - - ) : ( - <> - {isMobile ? ( - - ) : ( - - {renderBrandNav} - - - )} - {isMobile ? ( - <> - - {renderBrandNav} - - ) : ( - - )} - - )} - - - - ); -}; - -HeaderBody.propTypes = { - studioBaseUrl: PropTypes.string.isRequired, - logoutUrl: PropTypes.string.isRequired, - setModalPopupTarget: PropTypes.func.isRequired, - toggleModalPopup: PropTypes.func.isRequired, - isModalPopupOpen: PropTypes.bool.isRequired, - courseNumber: PropTypes.string, - courseOrg: PropTypes.string, - courseTitle: PropTypes.string, - logo: PropTypes.string, - logoAltText: PropTypes.string, - courseId: PropTypes.string, - authenticatedUserAvatar: PropTypes.string, - username: PropTypes.string, - isAdmin: PropTypes.bool, - isMobile: PropTypes.bool, - isHiddenMainMenu: PropTypes.bool, - // injected - intl: intlShape.isRequired, -}; - -HeaderBody.defaultProps = { - logo: null, - logoAltText: null, - courseId: null, - courseNumber: null, - courseOrg: null, - courseTitle: null, - authenticatedUserAvatar: null, - username: null, - isAdmin: false, - isMobile: false, - isHiddenMainMenu: false, -}; - -export default injectIntl(HeaderBody); diff --git a/src/studio-header/MobileHeader.jsx b/src/studio-header/MobileHeader.jsx deleted file mode 100644 index 26f88dd12..000000000 --- a/src/studio-header/MobileHeader.jsx +++ /dev/null @@ -1,69 +0,0 @@ -// This file was copied from edx/frontend-component-header-edx. -import React, { useState } from 'react'; -import PropTypes from 'prop-types'; -import { useToggle, ModalPopup } from '@edx/paragon'; -import HeaderBody from './HeaderBody'; -import MobileMenu from './MobileMenu'; - -const MobileHeader = ({ - studioBaseUrl, - courseId, - ...props -}) => { - const [isOpen, , close, toggle] = useToggle(false); - const [target, setTarget] = useState(null); - - return ( - <> - - - - - - ); -}; - -MobileHeader.propTypes = { - studioBaseUrl: PropTypes.string.isRequired, - logoutUrl: PropTypes.string.isRequired, - setModalPopupTarget: PropTypes.func.isRequired, - toggleModalPopup: PropTypes.func.isRequired, - isModalPopupOpen: PropTypes.bool.isRequired, - courseNumber: PropTypes.string, - courseOrg: PropTypes.string, - courseTitle: PropTypes.string, - logo: PropTypes.string, - logoAltText: PropTypes.string, - courseId: PropTypes.string, - authenticatedUserAvatar: PropTypes.string, - username: PropTypes.string, - isAdmin: PropTypes.bool, -}; - -MobileHeader.defaultProps = { - logo: null, - logoAltText: null, - courseId: null, - courseNumber: null, - courseOrg: null, - courseTitle: null, - authenticatedUserAvatar: null, - username: null, - isAdmin: false, -}; - -export default MobileHeader; diff --git a/src/studio-header/MobileMenu.jsx b/src/studio-header/MobileMenu.jsx deleted file mode 100644 index 0f35c8ffc..000000000 --- a/src/studio-header/MobileMenu.jsx +++ /dev/null @@ -1,77 +0,0 @@ -import PropTypes from 'prop-types'; -import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; -import { Collapsible } from '@edx/paragon'; -import messages from './messages'; -import { getContentMenuItem, getSettingMenuItems, getToolsMenuItems } from './utils'; - -const MobileMenu = ({ - studioBaseUrl, - courseId, - // injected - intl, -}) => { - const contentItems = getContentMenuItem({ studioBaseUrl, courseId, intl }); - const settingsItems = getSettingMenuItems({ studioBaseUrl, courseId, intl }); - const toolsItems = getToolsMenuItems({ studioBaseUrl, courseId, intl }); - - return ( -
-
- - - - - - - - - -
-
- ); -}; - -MobileMenu.propTypes = { - courseId: PropTypes.string.isRequired, - studioBaseUrl: PropTypes.string.isRequired, - // injected - intl: intlShape.isRequired, -}; - -export default injectIntl(MobileMenu); diff --git a/src/studio-header/NavDropdownMenu.jsx b/src/studio-header/NavDropdownMenu.jsx deleted file mode 100644 index 52c4cbe81..000000000 --- a/src/studio-header/NavDropdownMenu.jsx +++ /dev/null @@ -1,37 +0,0 @@ -import PropTypes from 'prop-types'; -import { - Dropdown, - DropdownButton, -} from '@edx/paragon'; - -const NavDropdownMenu = ({ - id, - buttonTitle, - items, -}) => ( - - {items.map(item => ( - - {item.title} - - ))} - -); - -NavDropdownMenu.propTypes = { - id: PropTypes.string.isRequired, - buttonTitle: PropTypes.string.isRequired, - items: PropTypes.arrayOf(PropTypes.shape({ - href: PropTypes.string, - title: PropTypes.string, - })).isRequired, -}; - -export default NavDropdownMenu; diff --git a/src/studio-header/UserMenu.jsx b/src/studio-header/UserMenu.jsx deleted file mode 100644 index 81579518a..000000000 --- a/src/studio-header/UserMenu.jsx +++ /dev/null @@ -1,68 +0,0 @@ -import PropTypes from 'prop-types'; -import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; -import { - Avatar, -} from '@edx/paragon'; -import NavDropdownMenu from './NavDropdownMenu'; -import { getUserMenuItems } from './utils'; - -const UserMenu = ({ - username, - studioBaseUrl, - logoutUrl, - authenticatedUserAvatar, - isMobile, - isAdmin, - // injected - intl, -}) => { - const avatar = authenticatedUserAvatar ? ( - {username} - ) : ( - - ); - const title = isMobile ? avatar : <>{avatar}{username}; - - return ( - - ); -}; - -UserMenu.propTypes = { - username: PropTypes.string, - studioBaseUrl: PropTypes.string.isRequired, - logoutUrl: PropTypes.string.isRequired, - authenticatedUserAvatar: PropTypes.string, - isMobile: PropTypes.bool, - isAdmin: PropTypes.bool, - // injected - intl: intlShape.isRequired, -}; - -UserMenu.defaultProps = { - isMobile: false, - isAdmin: false, - authenticatedUserAvatar: null, - username: null, -}; - -export default injectIntl(UserMenu); diff --git a/src/studio-header/header.scss b/src/studio-header/header.scss deleted file mode 100644 index 7596cd0d2..000000000 --- a/src/studio-header/header.scss +++ /dev/null @@ -1,145 +0,0 @@ -// This SCSS was partly copied from edx/frontend-app-support-tools/src/support-header/index.scss. -$spacer: 1rem; -$blue: #007DB8; -$white: #FFFFFF; - -.btn-tertiary:hover { - color: white; - background-color: #00262B; -} - -.course-title-lockup { - @media only screen and (max-width: 768px) { - padding-left: .5rem; - max-width: 70%; - } - - @media only screen and (min-width: 769px) { - padding: .5rem; - padding-right: $spacer; - border-right: 1px solid #E5E5E5; - min-width: 70%; - } - - overflow: hidden; - - span { - color: #333333; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - line-height: 1.375rem; - } -} - -.mobile-menu-container { - background-color: white; - - .pgn__modal-popup__arrow::after { - border-top-color: white; - } -} - -.dropdown-item a { - text-decoration: none; -} - -.mobile-menu-item { - padding: 8px 0; - - a { - color: #454545; - } -} - -// .icon-button { -// display: inline-flex; -// line-height: 3rem; -// background: transparent; -// vertical-align: middle; -// text-align: center; -// border: none; -// height: 3rem; -// width: 3rem; -// padding: .75rem; -// justify-content: center; -// align-items: center; - -// &:hover, -// &:focus { -// background: rgb(0 0 0 / .1); -// } -// } - -.site-header-mobile, -.site-header-desktop { - position: relative; - z-index: 1000; -} - -.site-header-mobile { - .nav-link { - text-decoration: none; - cursor: pointer; - } - - img { - height: 1.5rem; - } -} - -.site-header-desktop { - height: 3.75rem; - box-shadow: 0 1px 0 0 rgb(0 0 0 / .1); - background: $white; - - .nav-link { - text-decoration: none; - } - - .logo { - display: block; - box-sizing: content-box; - position: relative; - top: -.05em; - height: 1.75rem; - padding: $spacer 0; - margin-right: $spacer; - - img { - display: block; - height: 100%; - } - } - - .main-nav { - flex-wrap: nowrap; - - .nav-link { - padding: $spacer; - text-decoration: none; - font-weight: 500; - letter-spacing: .01em; - } - - .nav-link:hover, - .nav-link:focus, - .nav-link.active, - .expanded .nav-link { - background: $component-active-bg; - color: $component-active-color; - } - - .menu { - position: relative; - - .menu-content { - border-top: solid 2px $component-active-bg; - box-shadow: 0 1px 2px rgb(0 0 0 / .25); - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; - padding: $spacer; - } - } - } -} diff --git a/src/studio-home/StudioHome.jsx b/src/studio-home/StudioHome.jsx index 01b3e5c8c..3222a0e17 100644 --- a/src/studio-home/StudioHome.jsx +++ b/src/studio-home/StudioHome.jsx @@ -7,13 +7,13 @@ import { } from '@edx/paragon'; import { Add as AddIcon } from '@edx/paragon/icons/es5'; import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; +import { StudioFooter } from '@edx/frontend-component-footer'; import { getConfig } from '@edx/frontend-platform'; import Loading from '../generic/Loading'; import InternetConnectionAlert from '../generic/internet-connection-alert'; -import Header from '../studio-header/Header'; +import Header from '../header'; import SubHeader from '../generic/sub-header/SubHeader'; -import AppFooter from '../AppFooter'; import HomeSidebar from './home-sidebar'; import TabsSection from './tabs-section'; import OrganizationSection from './organization-section'; @@ -146,7 +146,7 @@ const StudioHome = ({ intl }) => { isQueryPending={anyQueryIsPending} /> - + ); };