Compare commits

..

207 Commits

Author SHA1 Message Date
Syed Ali Abbas Zaidi
678b95f60d feat: upgrade react router to v6 (#316)
* feat: upgrade react router to v6

* chore: update peer deps
2023-08-16 16:46:49 +05:00
renovate[bot]
599f513624 fix(deps): update dependency @edx/paragon to v20.46.2 2023-08-14 10:18:32 +00:00
renovate[bot]
e8ce471f6f fix(deps): update font awesome to v6.4.2 2023-08-14 06:15:41 +00:00
renovate[bot]
4e727748af chore(deps): update dependency @edx/frontend-platform to v4.6.1 2023-08-07 10:37:18 +00:00
renovate[bot]
79c5bbff68 chore(deps): update dependency @edx/frontend-build to v12.9.4 2023-08-07 08:25:09 +00:00
Jenkins
a95b600a00 chore(i18n): update translations 2023-08-06 16:31:03 -04:00
Awais Ansari
464e952a1e Merge pull request #379 from openedx/aansari/INF-993
feat: deprecate notification tray in learning header
2023-08-02 14:35:38 +05:00
Awais Ansari
018ca18a4e feat: deprecate notification tray in learning header 2023-08-01 18:50:12 +05:00
renovate[bot]
4b89e7561f chore(deps): update dependency jest to v29.6.2 2023-07-31 09:53:25 +00:00
renovate[bot]
da08e721c2 chore(deps): update dependency @edx/frontend-build to v12.9.3 2023-07-31 07:34:58 +00:00
renovate[bot]
d037e96a0c chore(deps): update dependency @testing-library/jest-dom to v5.17.0 2023-07-24 12:16:59 +00:00
renovate[bot]
050dd30d8f chore(deps): update dependency @edx/frontend-build to v12.9.2 2023-07-24 09:55:32 +00:00
renovate[bot]
3dd41030d3 fix(deps): update dependency @edx/paragon to v20.45.5 2023-07-24 06:29:20 +00:00
Awais Ansari
27228f093d Merge pull request #370 from openedx/Ayesha/INF-951
fix: clicking on notification redirecting to correct URL
2023-07-14 13:04:49 +05:00
Muhammad Adeel Tajamul
83f3241e26 fix: course name was not visible in notification (#371) 2023-07-14 08:53:02 +05:00
ayeshoali
e153aefc13 fix: clicking on notification redirecting to correct URL 2023-07-13 15:48:35 +05:00
Bilal Qamar
936c8714b7 fix: updated frontend-build to resolve word-wrap ReDoS vulnerability (#368) 2023-07-11 17:31:29 +05:00
renovate[bot]
6b18f28933 chore(deps): update dependency jest to v29.6.1 2023-07-10 10:41:00 +00:00
ayesha waris
0ce451cfd2 feat: integrated notifications tray with backend apis (#363)
* feat: integrated notifications tray with backend apis

* test: updates test cases

* refactor: loader added and resolves minor nits

* test: fixes test cases related to pagination

* refactor: moved pagination to normalised data
2023-07-10 13:18:44 +05:00
renovate[bot]
42e831a693 chore(deps): update dependency @edx/frontend-build to v12.8.60 2023-07-10 07:38:50 +00:00
Jenkins
9af7eaf587 chore(i18n): update translations 2023-07-09 16:30:57 -04:00
Bilal Qamar
3fbbde1044 fix: updated frontend-build to bump eslint version (#364) 2023-07-06 18:14:00 +05:00
Bilal Qamar
c3f0282be4 feat: update react & react-dom to v17 (#346)
* feat: update react & react-dom to v17

* build: update paragon version

* build: update lock file

* refactor: updated frontend-platform

---------

Co-authored-by: mashal-m <mashal.malik@arbisoft.com>
2023-07-05 12:04:53 +05:00
sundasnoreen12
ceb9c13542 Merge pull request #360 from openedx/sundas/INF-917
test: added test cases for UI components
2023-07-03 23:20:05 -07:00
SundasNoreen
7229bff3ff refactor: added mock funtion for notification count api 2023-07-03 16:30:03 +05:00
renovate[bot]
0695d4f400 fix(deps): update font awesome to v6.4.0 2023-07-03 08:13:31 +00:00
SundasNoreen
de8783c708 refactor: fixed review points 2023-06-27 16:28:58 +05:00
renovate[bot]
e2540bc3a0 fix(deps): update dependency @edx/paragon to v20.45.0 2023-06-26 19:55:23 +00:00
renovate[bot]
ffb5a765e2 chore(deps): update dependency @edx/reactifex to v2.2.0 2023-06-26 14:58:49 +00:00
renovate[bot]
952e543217 fix(deps): update dependency axios-mock-adapter to v1.21.5 2023-06-26 11:48:04 +00:00
SundasNoreen
0e6a272f2b test: added test cases for UI components 2023-06-26 13:39:09 +05:00
renovate[bot]
45a1da9f5e chore(deps): update dependency @edx/frontend-build to v12.8.57 2023-06-26 06:43:40 +00:00
sundasnoreen12
022515d1d2 Merge pull request #355 from openedx/sundas/INF-903
feat: binded show notification tray status with the backend api
2023-06-20 01:59:04 -07:00
ayeshoali
2d737aae7f refactor: fixed data updation in redux 2023-06-20 13:31:15 +05:00
SundasNoreen
4c4db14eac feat: binded show notification tray status with the backend api 2023-06-19 18:00:06 +05:00
sundasnoreen12
911cea6a0e Merge pull request #350 from openedx/sundas/INF-878
test: added redux, selector and api cases
2023-06-19 05:10:57 -07:00
SundasNoreen
a52ddfd9bd refactor: changed api url 2023-06-19 16:58:32 +05:00
SundasNoreen
8175ba897a test: added failed and denied test cases of redux 2023-06-19 16:04:55 +05:00
renovate[bot]
cfda72b2e2 chore(deps): update dependency @testing-library/dom to v9.3.1 2023-06-19 10:46:30 +00:00
SundasNoreen
4483a734bc refactor: fixed issues of review 2023-06-19 15:33:47 +05:00
renovate[bot]
db1903cdce chore(deps): update dependency @edx/frontend-build to v12.8.54 2023-06-19 08:12:52 +00:00
Jenkins
71851b13a6 chore(i18n): update translations 2023-06-18 16:30:53 -04:00
SundasNoreen
6efa31092d test: added redux, selector and api cases 2023-06-15 17:27:11 +05:00
SundasNoreen
c3541a3d79 test: added notification redux test cases 2023-06-15 13:30:38 +05:00
sundasnoreen12
dad01fcd78 Merge pull request #340 from openedx/sundas/INF-820
feat: added notification UI
2023-06-15 01:12:31 -07:00
ayeshoali
30e6eed60d refactor: fixes extra spaces in index.scss 2023-06-15 12:39:23 +05:00
renovate[bot]
de69ed3dd9 fix(deps): update dependency @edx/paragon to v20.44.0 2023-06-12 14:13:06 +00:00
renovate[bot]
1d55df323f chore(deps): update dependency @edx/frontend-build to v12.8.51 2023-06-12 11:46:29 +00:00
SundasNoreen
4e718f85de refactor: fixed all review points 2023-06-12 12:56:15 +05:00
SundasNoreen
a211547a1d refactor: removed backend api calls 2023-06-08 21:08:54 +05:00
Awais Ansari
784e9afccf fix: add appName param in getNotifications function 2023-06-06 15:16:06 +05:00
SundasNoreen
4b23d8c4e4 fix: lint issue 2023-06-06 13:15:12 +05:00
ayeshoali
6d02e63d08 fix: fixes lint errors 2023-06-06 13:04:20 +05:00
ayeshoali
b1feed2443 fix: fixes UI according to figma 2023-06-06 12:48:10 +05:00
SundasNoreen
cabf4e3f27 refactor: fixed code refactor and added new slices and selector 2023-06-05 19:55:46 +05:00
Awais Ansari
78a40d47c1 refactor: code and style modifications 2023-06-05 17:52:52 +05:00
renovate[bot]
c7178afe6b chore(deps): update dependency @edx/frontend-build to v12.8.40 2023-06-05 10:10:38 +00:00
Awais Ansari
18a6840037 fix: Ui modifications 2023-06-05 14:51:30 +05:00
renovate[bot]
583a487c38 chore(deps): update dependency @edx/frontend-platform to v4.5.1 2023-06-05 08:50:33 +00:00
SundasNoreen
3276496523 feat: added redux store implementation 2023-06-05 12:15:41 +05:00
Awais Ansari
7ab55175b5 fix: redux structure updates 2023-06-01 19:57:45 +05:00
SundasNoreen
72e82005c0 feat: added notification APIs 2023-06-01 13:07:53 +05:00
SundasNoreen
c4df727178 refactor: refactor components 2023-05-31 09:28:45 +05:00
renovate[bot]
1f6766175d chore(deps): update dependency @edx/frontend-platform to v4.5.0 2023-05-29 09:37:10 +00:00
renovate[bot]
2ac8988a9b chore(deps): update dependency @edx/frontend-build to v12.8.38 2023-05-29 07:50:58 +00:00
Awais Ansari
642be093c7 fix: bell icon design change 2023-05-26 20:52:18 +05:00
SundasNoreen
86939a2559 refactor: added notification icon in learning header 2023-05-26 17:07:05 +05:00
SundasNoreen
8ed18f3d69 refactor: UI refactor based on figma 2023-05-25 22:41:32 +05:00
SundasNoreen
061746da9f refactor: used paragon icons and updated css 2023-05-24 15:14:41 +05:00
SundasNoreen
de77aa5f0c feat: notification tray closes when clicked outside 2023-05-23 12:16:22 +05:00
SundasNoreen
7034d10536 refactor: fixed snapshot and store structure in header test file 2023-05-23 10:40:43 +05:00
SundasNoreen
4ce7311809 refactor: removed unused states 2023-05-22 15:17:04 +05:00
SundasNoreen
e76f5b6937 feat: added add more notification button functionality 2023-05-22 15:05:26 +05:00
SundasNoreen
f8fc794458 feat: added notification tray 2023-05-22 14:59:24 +05:00
sundasnoreen12
a5069edd94 feat: added notification UI 2023-05-15 16:36:41 +05:00
renovate[bot]
2543926c95 fix(deps): update dependency @edx/paragon to v20.36.0 2023-05-15 07:37:37 +00:00
renovate[bot]
c5eb43a2a5 chore(deps): update dependency @testing-library/dom to v9.3.0 2023-05-15 07:33:45 +00:00
renovate[bot]
256fa5c9d8 fix(deps): update dependency @edx/paragon to v20.34.0 2023-05-08 10:40:34 +00:00
renovate[bot]
267cce9f89 chore(deps): update dependency @edx/frontend-build to v12.8.27 2023-05-08 10:37:16 +00:00
renovate[bot]
4f59c80a12 fix(deps): update dependency @edx/paragon to v20.32.3 2023-05-01 07:58:51 +00:00
renovate[bot]
59afd596ab chore(deps): update dependency @edx/frontend-build to v12.8.16 2023-05-01 07:55:36 +00:00
Jenkins
0c83268163 chore(i18n): update translations 2023-04-23 16:30:51 -04:00
Bilal Qamar
c5f5fa9281 feat!: upgraded to node v18, added .nvmrc and updated workflows (#332)
BREAKING CHANGE: Ending support of @edx/frontend-platform v2 and v3 and now only support v4
2023-04-20 19:10:05 +05:00
Muhammad Abdullah Waheed
e247aee372 fix: updated readme for installing dependencies (#331) 2023-04-20 17:36:10 +05:00
Bilal Qamar
f6ae5a4bdd refactor: reverted in favor of major release due to updated platform peer dependencies (#330) 2023-04-20 16:52:44 +05:00
Brian Smith
057d16d3c1 fix: release frontend-platform version update 2023-04-19 13:04:58 -04:00
Omar Al-Ithawi
93bb38d0bd chore(deps): update frontend-platform version (#329)
gets the intl-imports.js script for FC-0012 OEP-58.
2023-04-13 16:56:46 -04:00
renovate[bot]
01405eaff9 fix(deps): update dependency @edx/paragon to v20.30.1 2023-04-10 14:48:47 +00:00
renovate[bot]
59fa6e2a35 chore(deps): update dependency @edx/frontend-build to v12.8.6 2023-04-10 11:18:27 +00:00
Mashal Malik
9fc3a0e835 refactor: update peer dependency for react and react-dom (#326)
* refactor: remove react16 from peer dependency

* build: update lock file

* fix: fix lint issue

* refactor: add 17 support of react in peerDep
2023-04-05 16:47:15 +05:00
renovate[bot]
22e157adf6 fix(deps): update dependency @edx/paragon to v20.29.0 2023-04-03 12:46:02 +00:00
renovate[bot]
6b81f69eba chore(deps): update dependency @testing-library/dom to v9.2.0 2023-04-03 10:35:08 +00:00
Bilal Qamar
cefa84006c fix: reverted semantic release to v16 (#321) 2023-03-30 11:04:45 +05:00
Muhammad Abdullah Waheed
a54309dd63 fix: updated version of semantic-release-action (#322) 2023-03-29 23:33:58 +05:00
Bilal Qamar
aeb0fd2be7 feat: upgraded to node v18, added .nvmrc and updated workflows (#314)
* feat: upgraded to node v18, added .nvmrc and updated workflows

* refactor: upgraded frontend-build & frontend-platform, updated workflows

* refactor: moved platform from devDependencies
2023-03-29 16:44:29 +05:00
renovate[bot]
26eb2bb4c7 chore(deps): update dependency @edx/frontend-platform to v3.6.0 2023-03-27 10:18:25 +00:00
renovate[bot]
8083079954 chore(deps): update dependency @edx/frontend-build to v12.7.0 2023-03-27 10:15:17 +00:00
renovate[bot]
d4fc8489ea fix(deps): update dependency @edx/paragon to v20.28.5 2023-03-20 11:56:19 +00:00
renovate[bot]
4020a81bd4 chore(deps): update dependency redux-saga to v1.2.3 2023-03-20 11:53:34 +00:00
renovate[bot]
acf1adba80 chore(deps): update dependency jest to v29.5.0 2023-03-13 09:54:48 +00:00
renovate[bot]
a204ff8c03 chore(deps): update dependency @testing-library/dom to v9.0.1 2023-03-13 09:47:40 +00:00
Mashal Malik
e8ccc4b707 chore: Update transifex api from v2 to v3 (#310)
* chore: Update transifex api from v2 to v3

* refactor: remove duplicate line
2023-03-06 17:58:12 +05:00
renovate[bot]
4d86780c73 chore(deps): update dependency @testing-library/dom to v9 2023-02-27 11:44:52 +00:00
renovate[bot]
fdbb83f51e fix(deps): update font awesome to v6.3.0 2023-02-27 11:38:21 +00:00
Feanil Patel
f6e4664d37 Merge pull request #304 from openedx/repo_checks/ensure_workflows
Update standard workflow files.
2023-02-24 11:45:23 -05:00
Feanil Patel
65177fcdcc build: Updating a missing workflow file add-depr-ticket-to-depr-board.yml.
The .github/workflows/add-depr-ticket-to-depr-board.yml workflow is missing or needs an update to stay in
sync with the current standard for this workflow as defined in the
`.github` repo of the `openedx` GitHub org.
2023-02-23 13:57:40 -05:00
Feanil Patel
7601249fb6 build: Creating a missing workflow file add-remove-label-on-comment.yml.
The .github/workflows/add-remove-label-on-comment.yml workflow is missing or needs an update to stay in
sync with the current standard for this workflow as defined in the
`.github` repo of the `openedx` GitHub org.
2023-02-23 13:57:40 -05:00
Feanil Patel
c8ef3dad93 build: Creating a missing workflow file self-assign-issue.yml.
The .github/workflows/self-assign-issue.yml workflow is missing or needs an update to stay in
sync with the current standard for this workflow as defined in the
`.github` repo of the `openedx` GitHub org.
2023-02-23 13:57:39 -05:00
renovate[bot]
b02fe00c71 fix(deps): update dependency @edx/paragon to v20.28.4 2023-02-20 11:19:51 +00:00
renovate[bot]
4404aede33 chore(deps): update dependency jest to v29.4.3 2023-02-20 11:12:57 +00:00
renovate[bot]
1b0edb10c4 chore(deps): update dependency @testing-library/dom to v8.20.0 2023-02-13 12:12:41 +00:00
renovate[bot]
546adff45e chore(deps): update dependency @edx/brand to v1.2.0 2023-02-13 12:05:28 +00:00
renovate[bot]
94b14fd618 chore(deps): update dependency redux-saga to v1.2.2 2023-02-06 13:51:48 +00:00
renovate[bot]
5b8a9a587b chore(deps): update dependency redux to v4.2.1 2023-02-06 13:44:55 +00:00
renovate[bot]
2650cb59b3 chore(deps): update actions/setup-node action to v3 (#212)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-06 15:11:28 +05:00
renovate[bot]
bc2b13175a chore(deps): update dependency husky to v8 (#235)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-06 14:30:50 +05:00
renovate[bot]
85e8094833 fix(deps): update font awesome to v6 (#281)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-06 14:17:48 +05:00
dependabot[bot]
aff8dda3ee chore(deps): bump decode-uri-component from 0.2.0 to 0.2.2 (#287)
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-01 17:15:00 +05:00
dependabot[bot]
51b505552d chore(deps): bump cookiejar from 2.1.3 to 2.1.4 (#296)
Bumps [cookiejar](https://github.com/bmeck/node-cookiejar) from 2.1.3 to 2.1.4.
- [Release notes](https://github.com/bmeck/node-cookiejar/releases)
- [Commits](https://github.com/bmeck/node-cookiejar/commits)

---
updated-dependencies:
- dependency-name: cookiejar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-01 17:14:36 +05:00
dependabot[bot]
3648f1b6be build(deps): bump json5 from 1.0.1 to 1.0.2
Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-30 14:12:31 +00:00
Bilal Qamar
c78b6964b9 chore: updated frontend-build version to v12.4.19 (#297) 2023-01-25 18:51:25 +05:00
renovate[bot]
664d05134b fix(deps): update dependency @edx/paragon to v20.27.0 2023-01-23 10:38:54 +00:00
renovate[bot]
b969522cd0 chore(deps): update dependency @edx/frontend-build to v12.4.16 2023-01-23 10:34:46 +00:00
renovate[bot]
0cd8210ea7 chore(deps): update dependency @testing-library/dom to v8.19.1 2023-01-16 10:17:13 +00:00
renovate[bot]
1c763c2102 chore(deps): update dependency @edx/frontend-build to v12.4.15 2023-01-09 09:27:54 +00:00
Mashal Malik
073003284a Moving code coverage from codecov package to CI (#289)
* fix: removed derpeciated package codecov

* fix: install edx/paragon 20.20.0 fixed version

* fix: specified paragron 20.20.0 version

Co-authored-by: Shahroz Ahmad <shahroz.ahmad@arbisoft.com>
2022-12-29 12:25:49 +05:00
Bilal Qamar
92fdf85c9a feat: paragon updated to v20 & frontend-build version updated
* feat: paragon updated to v20 & frontend-build version updated

* refactor: moved paragon from devDependencies to satisfy eslint rule

* refactor: updated snapshots
2022-12-09 15:57:09 +05:00
Sagirov Eugeniy
5ee8a8c75c feat: Account pages. Updated menu items urls. 2022-12-02 12:28:15 +00:00
Abdullah Waheed
536d67404f refactor: updated renovate config to auto update minor and patch versions of edx dependencies 2022-11-30 13:17:21 +00:00
Bilal Qamar
9d99bfcec6 refactor: updated snapshots 2022-11-25 16:53:50 +05:00
Bilal Qamar
3180c9d973 refactor: moved paragon from devDependencies to satisfy eslint rule 2022-11-25 16:48:29 +05:00
Bilal Qamar
1645274d9f feat: paragon updated to v20 & frontend-build version updated 2022-11-25 16:36:06 +05:00
Bilal Qamar
84e43cb038 refactor: bumped loader-utils 2022-11-25 16:26:11 +05:00
julianajlk
994b21c0c1 fix: Change frontend-platform peer dependency to v2 or v3 range 2022-11-14 20:19:37 +00:00
renovate[bot]
940b45ba7e chore(deps): update dependency jest to v29 2022-11-14 07:52:30 +00:00
dependabot[bot]
4efa0a07ae build(deps): bump loader-utils from 1.4.0 to 1.4.1 (#278)
Bumps [loader-utils](https://github.com/webpack/loader-utils) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v1.4.1/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v1.4.0...v1.4.1)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-10 17:34:00 +05:00
renovate[bot]
2bd6879bda chore(deps): update actions/checkout action to v3 (#211)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-11-10 17:18:45 +05:00
Muhammad Abdullah Waheed
b479f0b376 Merge pull request #205 from openedx/dependabot/npm_and_yarn/async-2.6.4
build(deps): bump async from 2.6.3 to 2.6.4
2022-11-08 18:40:15 +05:00
Leangseu Kim
dfdcbc0a8d feat: upgrade frontend platform to version 3 2022-11-07 12:45:43 +00:00
renovate[bot]
c3b02a2946 chore(deps): update dependency enzyme-adapter-react-16 to v1.15.7 2022-11-07 09:36:45 +00:00
renovate[bot]
f6c1a8bcc1 chore(deps): update dependency redux-saga to v1.2.1 2022-10-31 07:42:11 +00:00
Bilal Qamar
6c02962e0d refactor: updated frontend-build & resolved eslint issues 2022-10-26 10:37:57 -03:00
renovate[bot]
acaf98f0b1 chore(deps): update dependency @testing-library/dom to v8.19.0 2022-10-24 08:15:34 +00:00
Adolfo R. Brandes
90351083aa Merge pull request #256 from openedx/abdullahwaheed/transifex-languages-list-update
Supported Transifex languages in Makefile
2022-10-20 16:15:57 -03:00
Adolfo R. Brandes
6f75684ad9 Merge pull request #271 from brian-smith-tcril/studio-header-component
refactor: make studio header more flexible
2022-10-20 14:24:44 -03:00
Brian Smith
a54f099d68 refactor: make studio header more flexible 2022-10-19 10:20:10 -04:00
Diana Huang
02d081dd26 Merge pull request #270 from openedx/diana/transifex-call
fix: Add transifex flag.
2022-10-17 16:28:12 -04:00
Diana Huang
468acc80f0 fix: Add transifex flag.
The Transifex cli started requiring the -t or --translations flag in the pull command in order to fetch translations.

https://github.com/edx/edx-arch-experiments/issues/77
2022-10-17 16:05:53 -04:00
renovate[bot]
90fdd13fbc chore(deps): update dependency react-router-dom to v5.3.4 2022-10-17 08:57:14 +00:00
renovate[bot]
faf1b8522a chore(deps): update dependency react-redux to v7.2.9 2022-10-10 09:15:51 +00:00
Jenkins
e8a28b09bc chore(i18n): update translations 2022-10-09 16:30:19 -04:00
renovate[bot]
c611df3f69 chore(deps): update dependency jest-chain to v1.1.6 2022-10-03 08:05:06 +00:00
Jenkins
ab371f1c3a chore(i18n): update translations 2022-10-02 16:30:36 -04:00
renovate[bot]
fb2002a004 chore(deps): update dependency @testing-library/dom to v8.18.1 2022-09-26 10:35:10 +00:00
renovate[bot]
f955ec4434 chore(deps): update dependency @testing-library/dom to v8.18.0 2022-09-19 09:59:12 +00:00
Sarina Canelake
d529e00d7b Merge pull request #257 from openedx/tcril/fix-gh-org-url
Fix github url strings (org edx -> openedx)
2022-09-13 22:21:04 -04:00
renovate[bot]
e0cbbf7da1 chore(deps): update dependency @testing-library/dom to v8.17.1 2022-09-12 11:50:01 +00:00
Sarina Canelake
ba209fd050 fix: update path to .github workflows to read from openedx org 2022-09-10 18:07:21 -04:00
Sarina Canelake
ae7004e95d fix: fix github url strings (org edx -> openedx) 2022-09-07 09:02:25 -04:00
Abdullah Waheed
de9eb63b07 feat: added new translations in Makefile and updated all the translations 2022-09-06 20:05:09 +05:00
renovate[bot]
bf64a829cc chore(deps): update dependency @edx/frontend-platform to v2.6.2 2022-09-05 13:45:11 +00:00
renovate[bot]
1e1b06dfa5 chore(deps): update dependency @edx/frontend-platform to v2.6.1 2022-08-29 12:34:32 +00:00
renovate[bot]
469a93bd9c chore(deps): update dependency @testing-library/jest-dom to v5.16.5 2022-08-22 11:06:32 +00:00
Muhammad Abdullah Waheed
0645761f05 Merge pull request #250 from openedx/abdullahwaheed/run-build-in-ci
`npm run build` script in Github CI
2022-08-16 11:20:25 +05:00
renovate[bot]
20e9881546 chore(deps): update dependency @edx/frontend-platform to v2.5.2 2022-08-15 10:43:52 +00:00
Abdullah Waheed
42b347058f feat: added build script in github CI 2022-08-15 10:30:48 +05:00
renovate[bot]
b097535580 chore(deps): update dependency @edx/frontend-platform to v2.5.1 2022-08-08 12:39:35 +00:00
edx-semantic-release
d06929ca2b chore(i18n): update translations 2022-08-07 16:29:27 -04:00
renovate[bot]
0a9316c407 fix(deps): update dependency react-transition-group to v4.4.5 2022-08-02 00:28:16 +00:00
Kira Miller
d7704799fe Merge pull request #246 from openedx/kiram15/ENT-6064
chore: updating paragon dependecy
2022-08-01 15:18:47 -04:00
Kira
cc26f750e8 chore: updating paragon dependecy 2022-08-01 13:32:03 -04:00
renovate[bot]
8ac22515a6 chore(deps): update dependency @edx/frontend-platform to v2.5.0 2022-07-25 10:44:21 +00:00
renovate[bot]
b4a8d0afdc chore(deps): update dependency jest to v28.1.3 2022-07-18 12:07:45 +00:00
renovate[bot]
c131842139 chore(deps): update dependency @testing-library/dom to v8.16.0 2022-07-11 13:44:17 +00:00
renovate[bot]
acf5398b31 chore(deps): update dependency jest to v28 2022-07-04 12:55:37 +00:00
renovate[bot]
871e35d53a fix(deps): update dependency @fortawesome/react-fontawesome to ^0.2.0 2022-07-04 06:26:38 +00:00
connorhaugh
c8fb2ded56 Merge pull request #233 from openedx/feat--upgrade-frontend-build-
feat: upgrade frontend-build
2022-06-30 10:28:14 -04:00
connorhaugh
01ffe0b945 feat: upgrade frontend-build 2022-06-30 10:23:35 -04:00
connorhaugh
092c61dada Merge pull request #225 from openedx/renovate/edx-frontend-platform-2.x
chore(deps): update dependency @edx/frontend-platform to v2
2022-06-30 10:11:50 -04:00
renovate[bot]
cc43299932 chore(deps): update dependency @edx/frontend-platform to v2 2022-06-28 18:08:29 +00:00
renovate[bot]
9086b96313 chore(deps): update dependency @testing-library/dom to v8.14.0 2022-06-27 12:17:35 +00:00
renovate[bot]
86b9d4a061 chore(deps): update dependency @edx/paragon to v19.25.3 2022-06-20 12:10:31 +00:00
Renovate Bot
36fd9cb89a chore(deps): update dependency @testing-library/dom to v8 2022-06-13 14:57:57 +00:00
Renovate Bot
5aec913cd6 chore(deps): update dependency @edx/paragon to v19.25.1 2022-06-06 06:59:04 +00:00
Renovate Bot
5da9cc3ce4 chore(deps): update dependency @edx/paragon to v19.25.0 2022-05-30 10:10:04 +00:00
Renovate Bot
97e8c69345 chore(deps): update dependency @edx/paragon to v19.23.1 2022-05-23 13:08:03 +00:00
Renovate Bot
a410ec8ed6 chore(deps): update dependency react-router-dom to v5.3.3 2022-05-23 10:58:27 +00:00
Renovate Bot
7e197e2315 chore(deps): update dependency @edx/frontend-platform to v1.15.6 2022-05-16 19:03:38 +00:00
edX requirements bot
6373bc726f chore!: Dropped support for Node 12 (#216)
BREAKING CHANGE: Dropped support for Node 12
2022-05-16 20:57:50 +05:00
Renovate Bot
1ccf3214f0 chore(deps): update dependency @edx/paragon to v19.22.1 2022-05-16 10:16:14 +00:00
edx-semantic-release
137701d10c chore(i18n): update translations 2022-05-12 16:05:09 -04:00
Tim McCormack
37d39dba95 fix: Fix pull_translations by using correct CLI flag for language filter (#214)
Docs: https://developers.transifex.com/docs/using-the-client
2022-05-12 19:57:30 +00:00
Jawayria
5d297a0d00 feat: Added package-lock file version check (#213) 2022-05-12 12:23:43 +05:00
Renovate Bot
1aa6e80274 chore(deps): update dependency @edx/paragon to v19.20.0 2022-05-02 13:43:13 +00:00
Renovate Bot
15778a5e4a chore(deps): update dependency @edx/frontend-build to v9.2.2 2022-05-02 10:38:49 +00:00
Renovate Bot
48c41a7757 chore(deps): update dependency redux to v4.2.0 2022-04-25 14:19:34 +00:00
Renovate Bot
28ee7518f4 chore(deps): update dependency @edx/paragon to v19.19.0 2022-04-25 11:43:12 +00:00
Carlos Muniz
c35df7ef60 feat: Add StudioHeader with optional AppMenu (#199)
* feat: Add StudioHeader with optional AppMenu

StudioHeader is a graft of Header with an additional optional AppMenu.
Some Frontend Apps use Menus in their custom headers to provide more
functionality in their apps. By adding this functionality in
StudioHeader, it will be easier for frontend apps in Studio to adopt
this component without it affecting the main Header component.

* test: Add tests for StudioHeader and AppMenu

* fix: Remove orderHistory

* fix: Remove Responsive components

* fix: Redefine User Menu for Studio

The userMenu in StudioHeader will be used more for Studio related items
such as Studio Home and Studio Maintenance. This requires new messages
and reestablishing the url destinations of these menu items.

* fix: Remove loggedOutItems

* fix: Remove AUTHN_MINIMAL_HEADER items

* fix: Remove unnecessary tests

Anonymous sessions do not exist in the Studio. And Studio is not Mobile
Ready. Tests of these kind are superfluous and have been removed.

* feat: Turn mainMenu into an optional prop

* test: Add test for optional mainMenu prop

* feat: Update snapshots

* fix: Remove ResponsiveContext

* fix: Remove href and update appMenu prop

Dropping the href because having a link that also works as a dropdown
can be mildly confusing. Changing menu (type, href, content ) triplet
to stick to the pattern; so we removed "menu". Also adding brackets around
the triplet. Lastly, updating test and snapshot.

Co-authored-by: Carlos Muniz <cmuniz@trcil.org>
2022-04-21 13:43:37 -04:00
Renovate Bot
a8d5a0b62a chore(deps): update dependency react-router-dom to v5.3.1 2022-04-18 15:48:35 +00:00
dependabot[bot]
64f55150b6 build(deps): bump async from 2.6.3 to 2.6.4
Bumps [async](https://github.com/caolan/async) from 2.6.3 to 2.6.4.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/v2.6.4/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v2.6.3...v2.6.4)

---
updated-dependencies:
- dependency-name: async
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-18 11:56:29 +00:00
Renovate Bot
9ac38762eb chore(deps): update dependency react-redux to v7.2.8 2022-04-18 11:55:33 +00:00
Renovate Bot
72077302c0 chore(deps): update dependency jest to v27.5.1 2022-04-11 15:26:22 +00:00
Renovate Bot
f1a54ededf chore(deps): update dependency @testing-library/jest-dom to v5.16.4 2022-04-11 12:14:34 +00:00
Renovate Bot
709844a459 chore(deps): update dependency @edx/frontend-build to v9.1.4 2022-04-04 13:35:10 +00:00
Usama Sadiq
032c68edf2 Merge pull request #195 from openedx/jenkins/transifex-client-migration-541fe55
fix: transifex migration to new client
2022-04-04 14:10:03 +05:00
edX requirements bot
be8b6fba01 fix: transifex migration to new client 2022-03-17 08:56:54 -04:00
David Joy
541fe55d6e build: delete CODEOWNERS file
We no longer have a community-engineering team.
2022-03-04 10:42:58 -05:00
56 changed files with 9694 additions and 31537 deletions

View File

@@ -1,10 +1,13 @@
ACCESS_TOKEN_COOKIE_NAME=edx-jwt-cookie-header-payload
ACCOUNT_PROFILE_URL=http://localhost:1995
ACCOUNT_SETTINGS_URL=http://localhost:1997
BASE_URL=localhost:8080
CREDENTIALS_BASE_URL=http://localhost:18150
CSRF_TOKEN_API_PATH=/csrf/api/v1/token
ECOMMERCE_BASE_URL=http://localhost:18130
LANGUAGE_PREFERENCE_COOKIE_NAME=openedx-language-preference
LMS_BASE_URL=http://localhost:18000
STUDIO_BASE_URL=http://localhost:18010
LOGIN_URL=http://localhost:18000/login
LOGOUT_URL=http://localhost:18000/logout
MARKETING_SITE_BASE_URL=http://localhost:18000

View File

@@ -1,3 +1,4 @@
// eslint-disable-next-line import/no-extraneous-dependencies
const { createConfig } = require('@edx/frontend-build');
module.exports = createConfig('eslint');
module.exports = createConfig('eslint');

1
.github/CODEOWNERS vendored
View File

@@ -1 +0,0 @@
* @edx/community-engineering

View File

@@ -16,4 +16,4 @@ jobs:
secrets:
GITHUB_APP_ID: ${{ secrets.GRAPHQL_AUTH_APP_ID }}
GITHUB_APP_PRIVATE_KEY: ${{ secrets.GRAPHQL_AUTH_APP_PEM }}
SLACK_BOT_TOKEN: ${{ secrets.SLACK_ISSUE_BOT_TOKEN }}
SLACK_BOT_TOKEN: ${{ secrets.SLACK_ISSUE_BOT_TOKEN }}

View File

@@ -0,0 +1,20 @@
# This workflow runs when a comment is made on the ticket
# If the comment starts with "label: " it tries to apply
# the label indicated in rest of comment.
# If the comment starts with "remove label: ", it tries
# to remove the indicated label.
# Note: Labels are allowed to have spaces and this script does
# not parse spaces (as often a space is legitimate), so the command
# "label: really long lots of words label" will apply the
# label "really long lots of words label"
name: Allows for the adding and removing of labels via comment
on:
issue_comment:
types: [created]
jobs:
add_remove_labels:
uses: openedx/.github/.github/workflows/add-remove-label-on-comment.yml@master

View File

@@ -2,25 +2,24 @@ name: Default CI
on:
push:
branches:
- 'master'
- master
pull_request:
branches:
- '**'
- '**'
jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
node: [12, 14, 16]
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Nodejs Env
run: echo "NODE_VER=`cat .nvmrc`" >> $GITHUB_ENV
- name: Setup Nodejs
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
node-version: ${{ env.NODE_VER }}
- name: Install dependencies
run: npm ci
- name: Validate package-lock.json changes
@@ -29,7 +28,9 @@ jobs:
run: npm run lint
- name: Test
run: npm run test
- name: Build
run: npm run build
- name: i18n_extract
run: npm run i18n_extract
- name: Coverage
uses: codecov/codecov-action@v2
uses: codecov/codecov-action@v3

View File

@@ -7,4 +7,4 @@ on:
jobs:
commitlint:
uses: edx/.github/.github/workflows/commitlint.yml@master
uses: openedx/.github/.github/workflows/commitlint.yml@master

View File

@@ -0,0 +1,13 @@
#check package-lock file version
name: lockfileVersion check
on:
push:
branches:
- master
pull_request:
jobs:
version-check:
uses: openedx/.github/.github/workflows/lockfileversion-check-v3.yml@master

View File

@@ -2,38 +2,40 @@ name: Release CI
on:
push:
branches:
- master
- master
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: 12
- name: Install dependencies
run: npm ci
- name: Validate package-lock.json changes
run: make validate-no-uncommitted-package-lock-changes
- name: Lint
run: npm run lint
- name: Test
run: npm run test
- name: i18n_extract
run: npm run i18n_extract
- name: Coverage
uses: codecov/codecov-action@v2
- name: Build
run: npm run build
- name: Release
uses: cycjimmy/semantic-release-action@v2
with:
semantic_version: 16
env:
GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.SEMANTIC_RELEASE_NPM_TOKEN }}
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Nodejs Env
run: echo "NODE_VER=`cat .nvmrc`" >> $GITHUB_ENV
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VER }}
- name: Install dependencies
run: npm ci
- name: Validate package-lock.json changes
run: make validate-no-uncommitted-package-lock-changes
- name: Lint
run: npm run lint
- name: Test
run: npm run test
- name: i18n_extract
run: npm run i18n_extract
- name: Coverage
uses: codecov/codecov-action@v3
- name: Build
run: npm run build
- name: Release
uses: cycjimmy/semantic-release-action@v3
with:
semantic_version: 16
env:
GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.SEMANTIC_RELEASE_NPM_TOKEN }}

12
.github/workflows/self-assign-issue.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
# This workflow runs when a comment is made on the ticket
# If the comment starts with "assign me" it assigns the author to the
# ticket (case insensitive)
name: Assign comment author to ticket if they say "assign me"
on:
issue_comment:
types: [created]
jobs:
self_assign_by_comment:
uses: openedx/.github/.github/workflows/self-assign-issue.yml@master

2
.gitignore vendored
View File

@@ -7,3 +7,5 @@ temp
src/i18n/transifex_input.json
module.config.js
.idea/
.vscode

1
.nvmrc Normal file
View File

@@ -0,0 +1 @@
18

View File

@@ -1,8 +1,9 @@
[main]
host = https://www.transifex.com
[edx-platform.frontend-component-header]
[o:open-edx:p:edx-platform:r:frontend-component-header]
file_filter = src/i18n/messages/<lang>.json
source_file = src/i18n/transifex_input.json
source_lang = en
type = KEYVALUEJSON
type = KEYVALUEJSON

View File

@@ -1,11 +1,9 @@
transifex_resource = frontend-component-header
transifex_langs = "ar,fr,fr_CA,es_419,zh_CN"
export TRANSIFEX_RESOURCE = frontend-component-header
transifex_langs = "ar,fr,es_419,zh_CN,pt,it,de,uk,ru,hi,fr_CA"
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
@@ -42,15 +40,15 @@ push_translations:
# Pushing strings to Transifex...
tx push -s
# Fetching hashes from Transifex...
./node_modules/reactifex/bash_scripts/get_hashed_strings.sh $(tx_url1)
./node_modules/@edx/reactifex/bash_scripts/get_hashed_strings_v3.sh
# Writing out comments to file...
$(transifex_utils) $(transifex_temp) --comments
$(transifex_utils) $(transifex_temp) --comments --v3-scripts-path
# Pushing comments to Transifex...
./node_modules/reactifex/bash_scripts/put_comments.sh $(tx_url2)
./node_modules/@edx/reactifex/bash_scripts/put_comments_v3.sh
# Pulls translations from Transifex.
pull_translations:
tx pull -f --mode reviewed --language=$(transifex_langs)
tx pull -t -f --mode reviewed --languages=$(transifex_langs)
# This target is used by Travis.
validate-no-uncommitted-package-lock-changes:

View File

@@ -14,7 +14,7 @@ A generic header for Open edX micro-frontend applications.
Requirements
************
This component uses ``@edx/frontend-platform`` services such as i18n, analytics, configuration, and the ``AppContext`` React component, and expects that it has been loaded into a micro-frontend that has been properly initialized via ``@edx/frontend-platform``'s ``initialize`` function. `Please visit the frontend template application to see an example. <https://github.com/edx/frontend-template-application/blob/master/src/index.jsx>`_
This component uses ``@edx/frontend-platform`` services such as i18n, analytics, configuration, and the ``AppContext`` React component, and expects that it has been loaded into a micro-frontend that has been properly initialized via ``@edx/frontend-platform``'s ``initialize`` function. `Please visit the frontend template application to see an example. <https://github.com/openedx/frontend-template-application/blob/master/src/index.jsx>`_
Environment Variables
=====================
@@ -26,6 +26,8 @@ Environment Variables
Defaults to "localhost" in development.
* ``LOGO_URL`` - The URL of the site's logo. This logo is displayed in the header.
* ``ORDER_HISTORY_URL`` - The URL of the order history page.
* ``ACCOUNT_PROFILE_URL`` - The URL of the account profile page.
* ``ACCOUNT_SETTINGS_URL`` - The URL of the account settings page.
* ``AUTHN_MINIMAL_HEADER`` - A boolean flag which hides the main menu, user menu, and logged-out
menu items when truthy. This is intended to be used in micro-frontends like
frontend-app-authentication in which these menus are considered distractions from the user's task.
@@ -53,8 +55,8 @@ This library has the following exports:
Examples
========
* `An example of component and messages usage. <https://github.com/edx/frontend-template-application/blob/3355bb3a96232390e9056f35b06ffa8f105ed7ca/src/index.jsx#L21>`_
* `An example of SCSS file usage. <https://github.com/edx/frontend-template-application/blob/3cd5485bf387b8c479baf6b02bf59e3061dc3465/src/index.scss#L8>`_
* `An example of component and messages usage. <https://github.com/openedx/frontend-template-application/blob/3355bb3a96232390e9056f35b06ffa8f105ed7ca/src/index.jsx#L21>`_
* `An example of SCSS file usage. <https://github.com/openedx/frontend-template-application/blob/3cd5485bf387b8c479baf6b02bf59e3061dc3465/src/index.scss#L8>`_
***********
@@ -63,7 +65,7 @@ Development
Install dependencies::
npm i
npm ci
Start the development server::

39781
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -24,53 +24,53 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/edx/frontend-component-header.git"
"url": "git+https://github.com/openedx/frontend-component-header.git"
},
"author": "edX",
"license": "AGPL-3.0",
"bugs": {
"url": "https://github.com/edx/frontend-component-header/issues"
"url": "https://github.com/openedx/frontend-component-header/issues"
},
"homepage": "https://github.com/edx/frontend-component-header#readme",
"homepage": "https://github.com/openedx/frontend-component-header#readme",
"devDependencies": {
"@edx/brand": "npm:@edx/brand-openedx@1.1.0",
"@edx/frontend-build": "9.1.1",
"@edx/frontend-platform": "1.15.1",
"@edx/paragon": "19.6.0",
"codecov": "3.8.3",
"@edx/brand": "npm:@edx/brand-openedx@1.2.0",
"@edx/browserslist-config": "^1.1.1",
"@edx/frontend-build": "12.9.4",
"@edx/frontend-platform": "5.0.0",
"@edx/reactifex": "^2.1.1",
"@testing-library/dom": "9.3.1",
"@testing-library/jest-dom": "5.17.0",
"@testing-library/react": "10.4.9",
"@wojtekmaj/enzyme-adapter-react-17": "0.8.0",
"enzyme": "3.11.0",
"enzyme-adapter-react-16": "1.15.6",
"husky": "7.0.4",
"husky": "8.0.3",
"jest": "29.6.2",
"jest-chain": "1.1.6",
"prop-types": "15.8.1",
"react": "16.14.0",
"react-dom": "16.14.0",
"react-redux": "7.2.6",
"react-router-dom": "5.3.0",
"react-test-renderer": "16.14.0",
"reactifex": "1.1.1",
"redux": "4.1.2",
"redux-saga": "1.1.3",
"@testing-library/dom": "7.31.2",
"@testing-library/jest-dom": "5.16.2",
"jest": "27.5.0",
"jest-chain": "1.1.5",
"@testing-library/react": "10.4.9"
"react": "17.0.2",
"react-dom": "17.0.2",
"react-redux": "7.2.9",
"react-router-dom": "6.14.2",
"react-test-renderer": "17.0.2",
"redux": "4.2.1",
"redux-saga": "1.2.3"
},
"dependencies": {
"@edx/paragon": "20.46.2",
"@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.2",
"@fortawesome/fontawesome-svg-core": "1.2.36",
"@fortawesome/free-brands-svg-icons": "5.15.4",
"@fortawesome/free-regular-svg-icons": "5.15.4",
"@fortawesome/free-solid-svg-icons": "5.15.4",
"@fortawesome/react-fontawesome": "^0.1.14"
"react-transition-group": "4.4.5"
},
"peerDependencies": {
"@edx/frontend-platform": "^1.8.0",
"@edx/paragon": ">= 7.0.0 < 20.0.0",
"@edx/frontend-platform": "^4.0.0 || ^5.0.0",
"prop-types": "^15.5.10",
"react": "^16.9.0",
"react-dom": "^16.9.0"
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
}
}

View File

@@ -22,6 +22,11 @@
"pin"
],
"automerge": true
},
{
"matchPackagePatterns": ["@edx"],
"matchUpdateTypes": ["minor", "patch"],
"automerge": true
}
],
"timezone": "America/New_York"

View File

@@ -3,12 +3,12 @@ import PropTypes from 'prop-types';
import { AvatarIcon } from './Icons';
function Avatar({
const Avatar = ({
size,
src,
alt,
className,
}) {
}) => {
const avatar = src ? (
<img className="d-block w-100 h-100" src={src} alt={alt} />
) : (
@@ -23,7 +23,7 @@ function Avatar({
{avatar}
</span>
);
}
};
Avatar.propTypes = {
src: PropTypes.string,

View File

@@ -54,6 +54,24 @@ class DesktopHeader extends React.Component {
});
}
// Renders an optional App Menu for
renderAppMenu() {
const { appMenu } = this.props;
const { content: appMenuContent, menuItems } = appMenu;
return (
<Menu transitionClassName="menu-dropdown" transitionTimeout={250}>
<MenuTrigger tag="a" className="nav-link d-inline-flex align-items-center">
{appMenuContent} <CaretIcon role="img" aria-hidden focusable="false" />
</MenuTrigger>
<MenuContent className="mb-0 dropdown-menu show dropdown-menu-right pin-right shadow py-2">
{menuItems.map(({ type, href, content }) => (
<a className={`dropdown-${type}`} key={`${type}-${content}`} href={href}>{content}</a>
))}
</MenuContent>
</Menu>
);
}
renderUserMenu() {
const {
userMenu,
@@ -102,6 +120,7 @@ class DesktopHeader extends React.Component {
logoDestination,
loggedIn,
intl,
appMenu,
} = this.props;
const logoProps = { src: logo, alt: logoAltText, href: logoDestination };
const logoClasses = getConfig().AUTHN_MINIMAL_HEADER ? 'mw-100' : null;
@@ -118,6 +137,14 @@ class DesktopHeader extends React.Component {
>
{this.renderMainMenu()}
</nav>
{appMenu ? (
<nav
aria-label={intl.formatMessage(messages['header.label.app.nav'])}
className="nav app-nav"
>
{this.renderAppMenu()}
</nav>
) : null}
<nav
aria-label={intl.formatMessage(messages['header.label.secondary.nav'])}
className="nav secondary-menu-container align-items-center ml-auto"
@@ -155,6 +182,20 @@ DesktopHeader.propTypes = {
// i18n
intl: intlShape.isRequired,
// appMenu
appMenu: PropTypes.shape(
{
content: PropTypes.string,
menuItems: PropTypes.arrayOf(
PropTypes.shape({
type: PropTypes.string,
href: PropTypes.string,
content: PropTypes.string,
}),
),
},
),
};
DesktopHeader.defaultProps = {
@@ -167,6 +208,7 @@ DesktopHeader.defaultProps = {
avatar: null,
username: null,
loggedIn: false,
appMenu: null,
};
export default injectIntl(DesktopHeader);

View File

@@ -30,7 +30,7 @@ subscribe(APP_CONFIG_INITIALIZED, () => {
}, 'Header additional config');
});
function Header({ intl }) {
const Header = ({ intl }) => {
const { authenticatedUser, config } = useContext(AppContext);
const mainMenu = [
@@ -55,12 +55,12 @@ function Header({ intl }) {
},
{
type: 'item',
href: `${config.LMS_BASE_URL}/u/${authenticatedUser.username}`,
href: `${config.ACCOUNT_PROFILE_URL}/u/${authenticatedUser.username}`,
content: intl.formatMessage(messages['header.user.menu.profile']),
},
{
type: 'item',
href: `${config.LMS_BASE_URL}/account/settings`,
href: config.ACCOUNT_SETTINGS_URL,
content: intl.formatMessage(messages['header.user.menu.account.settings']),
},
{
@@ -110,7 +110,7 @@ function Header({ intl }) {
</Responsive>
</>
);
}
};
Header.propTypes = {
intl: intlShape.isRequired,

View File

@@ -56,6 +56,16 @@ const messages = defineMessages({
defaultMessage: 'Sign Up',
description: 'Link to registration',
},
'header.user.menu.studio.home': {
id: 'header.user.menu.studio.home',
defaultMessage: 'Studio Home',
description: 'Link to the Studio Home',
},
'header.user.menu.studio.maintenance': {
id: 'header.user.menu.studio.maintenance',
defaultMessage: 'Maintenance',
description: 'Link to the Studio Maintenance',
},
'header.label.account.nav': {
id: 'header.label.account.nav',
defaultMessage: 'Account',
@@ -96,6 +106,11 @@ const messages = defineMessages({
defaultMessage: 'Skip to main content',
description: 'A link used by screen readers to allow users to skip to the main content of the page.',
},
'header.label.app.nav': {
id: 'header.label.app.nav',
defaultMessage: 'App',
description: 'The aria label for the app Nav',
},
});
export default messages;

View File

@@ -1,3 +1,4 @@
/* eslint-disable react/prop-types */
import React from 'react';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import TestRenderer from 'react-test-renderer';
@@ -6,28 +7,31 @@ import { Context as ResponsiveContext } from 'react-responsive';
import Header from './index';
const HeaderComponent = ({ width, contextValue }) => (
<ResponsiveContext.Provider value={width}>
<IntlProvider locale="en" messages={{}}>
<AppContext.Provider
value={contextValue}
>
<Header />
</AppContext.Provider>
</IntlProvider>
</ResponsiveContext.Provider>
);
describe('<Header />', () => {
it('renders correctly for anonymous desktop', () => {
const component = (
<ResponsiveContext.Provider value={{ width: 1280 }}>
<IntlProvider locale="en" messages={{}}>
<AppContext.Provider
value={{
authenticatedUser: null,
config: {
LMS_BASE_URL: process.env.LMS_BASE_URL,
SITE_NAME: process.env.SITE_NAME,
LOGIN_URL: process.env.LOGIN_URL,
LOGOUT_URL: process.env.LOGOUT_URL,
LOGO_URL: process.env.LOGO_URL,
},
}}
>
<Header />
</AppContext.Provider>
</IntlProvider>
</ResponsiveContext.Provider>
);
const contextValue = {
authenticatedUser: null,
config: {
LMS_BASE_URL: process.env.LMS_BASE_URL,
SITE_NAME: process.env.SITE_NAME,
LOGIN_URL: process.env.LOGIN_URL,
LOGOUT_URL: process.env.LOGOUT_URL,
LOGO_URL: process.env.LOGO_URL,
},
};
const component = <HeaderComponent width={{ width: 1280 }} contextValue={contextValue} />;
const wrapper = TestRenderer.create(component);
@@ -35,31 +39,22 @@ describe('<Header />', () => {
});
it('renders correctly for authenticated desktop', () => {
const component = (
<ResponsiveContext.Provider value={{ width: 1280 }}>
<IntlProvider locale="en" messages={{}}>
<AppContext.Provider
value={{
authenticatedUser: {
userId: 'abc123',
username: 'edX',
roles: [],
administrator: false,
},
config: {
LMS_BASE_URL: process.env.LMS_BASE_URL,
SITE_NAME: process.env.SITE_NAME,
LOGIN_URL: process.env.LOGIN_URL,
LOGOUT_URL: process.env.LOGOUT_URL,
LOGO_URL: process.env.LOGO_URL,
},
}}
>
<Header />
</AppContext.Provider>
</IntlProvider>
</ResponsiveContext.Provider>
);
const contextValue = {
authenticatedUser: {
userId: 'abc123',
username: 'edX',
roles: [],
administrator: false,
},
config: {
LMS_BASE_URL: process.env.LMS_BASE_URL,
SITE_NAME: process.env.SITE_NAME,
LOGIN_URL: process.env.LOGIN_URL,
LOGOUT_URL: process.env.LOGOUT_URL,
LOGO_URL: process.env.LOGO_URL,
},
};
const component = <HeaderComponent width={{ width: 1280 }} contextValue={contextValue} />;
const wrapper = TestRenderer.create(component);
@@ -67,26 +62,17 @@ describe('<Header />', () => {
});
it('renders correctly for anonymous mobile', () => {
const component = (
<ResponsiveContext.Provider value={{ width: 500 }}>
<IntlProvider locale="en" messages={{}}>
<AppContext.Provider
value={{
authenticatedUser: null,
config: {
LMS_BASE_URL: process.env.LMS_BASE_URL,
SITE_NAME: process.env.SITE_NAME,
LOGIN_URL: process.env.LOGIN_URL,
LOGOUT_URL: process.env.LOGOUT_URL,
LOGO_URL: process.env.LOGO_URL,
},
}}
>
<Header />
</AppContext.Provider>
</IntlProvider>
</ResponsiveContext.Provider>
);
const contextValue = {
authenticatedUser: null,
config: {
LMS_BASE_URL: process.env.LMS_BASE_URL,
SITE_NAME: process.env.SITE_NAME,
LOGIN_URL: process.env.LOGIN_URL,
LOGOUT_URL: process.env.LOGOUT_URL,
LOGO_URL: process.env.LOGO_URL,
},
};
const component = <HeaderComponent width={{ width: 500 }} contextValue={contextValue} />;
const wrapper = TestRenderer.create(component);
@@ -94,31 +80,22 @@ describe('<Header />', () => {
});
it('renders correctly for authenticated mobile', () => {
const component = (
<ResponsiveContext.Provider value={{ width: 500 }}>
<IntlProvider locale="en" messages={{}}>
<AppContext.Provider
value={{
authenticatedUser: {
userId: 'abc123',
username: 'edX',
roles: [],
administrator: false,
},
config: {
LMS_BASE_URL: process.env.LMS_BASE_URL,
SITE_NAME: process.env.SITE_NAME,
LOGIN_URL: process.env.LOGIN_URL,
LOGOUT_URL: process.env.LOGOUT_URL,
LOGO_URL: process.env.LOGO_URL,
},
}}
>
<Header />
</AppContext.Provider>
</IntlProvider>
</ResponsiveContext.Provider>
);
const contextValue = {
authenticatedUser: {
userId: 'abc123',
username: 'edX',
roles: [],
administrator: false,
},
config: {
LMS_BASE_URL: process.env.LMS_BASE_URL,
SITE_NAME: process.env.SITE_NAME,
LOGIN_URL: process.env.LOGIN_URL,
LOGOUT_URL: process.env.LOGOUT_URL,
LOGO_URL: process.env.LOGO_URL,
},
};
const component = <HeaderComponent width={{ width: 500 }} contextValue={contextValue} />;
const wrapper = TestRenderer.create(component);

View File

@@ -1,6 +1,6 @@
import React from 'react';
export const MenuIcon = props => (
export const MenuIcon = (props) => (
<svg
width="24px"
height="24px"
@@ -14,7 +14,7 @@ export const MenuIcon = props => (
</svg>
);
export const AvatarIcon = props => (
export const AvatarIcon = (props) => (
<svg
width="24px"
height="24px"
@@ -29,7 +29,7 @@ export const AvatarIcon = props => (
</svg>
);
export const CaretIcon = props => (
export const CaretIcon = (props) => (
<svg
width="16px"
height="16px"

View File

@@ -1,29 +1,25 @@
import React from 'react';
import PropTypes from 'prop-types';
function Logo({ src, alt, ...attributes }) {
return (
<img src={src} alt={alt} {...attributes} />
);
}
const Logo = ({ src, alt, ...attributes }) => (
<img src={src} alt={alt} {...attributes} />
);
Logo.propTypes = {
src: PropTypes.string.isRequired,
alt: PropTypes.string.isRequired,
};
function LinkedLogo({
const LinkedLogo = ({
href,
src,
alt,
...attributes
}) {
return (
<a href={href} {...attributes}>
<img className="d-block" src={src} alt={alt} />
</a>
);
}
}) => (
<a href={href} {...attributes}>
<img className="d-block" src={src} alt={alt} />
</a>
);
LinkedLogo.propTypes = {
href: PropTypes.string.isRequired,

View File

@@ -2,12 +2,10 @@ import React from 'react';
import { CSSTransition } from 'react-transition-group';
import PropTypes from 'prop-types';
function MenuTrigger({ tag, className, ...attributes }) {
return React.createElement(tag, {
className: `menu-trigger ${className}`,
...attributes,
});
}
const MenuTrigger = ({ tag, className, ...attributes }) => React.createElement(tag, {
className: `menu-trigger ${className}`,
...attributes,
});
MenuTrigger.propTypes = {
tag: PropTypes.string,
className: PropTypes.string,
@@ -18,12 +16,10 @@ MenuTrigger.defaultProps = {
};
const MenuTriggerType = <MenuTrigger />.type;
function MenuContent({ tag, className, ...attributes }) {
return React.createElement(tag, {
className: ['menu-content', className].join(' '),
...attributes,
});
}
const MenuContent = ({ tag, className, ...attributes }) => React.createElement(tag, {
className: ['menu-content', className].join(' '),
...attributes,
});
MenuContent.propTypes = {
tag: PropTypes.string,
className: PropTypes.string,

200
src/StudioHeader.jsx Normal file
View File

@@ -0,0 +1,200 @@
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { AppContext } from '@edx/frontend-platform/react';
import {
APP_CONFIG_INITIALIZED,
ensureConfig,
getConfig,
mergeConfig,
subscribe,
} from '@edx/frontend-platform';
import { ActionRow } from '@edx/paragon';
import { Menu, MenuTrigger, MenuContent } from './Menu';
import Avatar from './Avatar';
import { LinkedLogo, Logo } from './Logo';
import { CaretIcon } from './Icons';
import messages from './Header.messages';
ensureConfig([
'STUDIO_BASE_URL',
'LOGOUT_URL',
'LOGIN_URL',
'SITE_NAME',
'LOGO_URL',
'ORDER_HISTORY_URL',
], 'StudioHeader component');
subscribe(APP_CONFIG_INITIALIZED, () => {
mergeConfig({
AUTHN_MINIMAL_HEADER: !!process.env.AUTHN_MINIMAL_HEADER,
}, 'StudioHeader additional config');
});
class StudioDesktopHeaderBase extends React.Component {
constructor(props) { // eslint-disable-line no-useless-constructor
super(props);
}
renderUserMenu() {
const {
userMenu,
avatar,
username,
intl,
} = this.props;
return (
<Menu transitionClassName="menu-dropdown" transitionTimeout={250}>
<MenuTrigger
tag="button"
aria-label={intl.formatMessage(messages['header.label.account.menu.for'], { username })}
className="btn btn-outline-primary d-inline-flex align-items-center pl-2 pr-3"
>
<Avatar size="1.5em" src={avatar} alt="" className="mr-2" />
{username} <CaretIcon role="img" aria-hidden focusable="false" />
</MenuTrigger>
<MenuContent className="mb-0 dropdown-menu show dropdown-menu-right pin-right shadow py-2">
{userMenu.map(({ type, href, content }) => (
<a className={`dropdown-${type}`} key={`${type}-${content}`} href={href}>{content}</a>
))}
</MenuContent>
</Menu>
);
}
renderLoggedOutItems() {
const { loggedOutItems } = this.props;
return loggedOutItems.map((item, i, arr) => (
<a
key={`${item.type}-${item.content}`}
className={i < arr.length - 1 ? 'btn mr-2 btn-link' : 'btn mr-2 btn-outline-primary'}
href={item.href}
>
{item.content}
</a>
));
}
render() {
const {
logo,
logoAltText,
logoDestination,
loggedIn,
intl,
actionRowContent,
} = this.props;
const logoProps = { src: logo, alt: logoAltText, href: logoDestination };
const logoClasses = getConfig().AUTHN_MINIMAL_HEADER ? 'mw-100' : null;
return (
<header className="site-header-desktop">
<a className="nav-skip sr-only sr-only-focusable" href="#main">{intl.formatMessage(messages['header.label.skip.nav'])}</a>
<div className={`container-fluid ${logoClasses}`}>
<div className="nav-container position-relative d-flex align-items-center">
{logoDestination === null ? <Logo className="logo" src={logo} alt={logoAltText} /> : <LinkedLogo className="logo" {...logoProps} />}
<ActionRow>
{actionRowContent}
<nav
aria-label={intl.formatMessage(messages['header.label.secondary.nav'])}
className="nav secondary-menu-container align-items-center ml-auto"
>
{loggedIn ? this.renderUserMenu() : this.renderLoggedOutItems()}
</nav>
</ActionRow>
</div>
</div>
</header>
);
}
}
StudioDesktopHeaderBase.propTypes = {
userMenu: PropTypes.arrayOf(PropTypes.shape({
type: PropTypes.oneOf(['item', 'menu']),
href: PropTypes.string,
content: PropTypes.string,
})),
loggedOutItems: PropTypes.arrayOf(PropTypes.shape({
type: PropTypes.oneOf(['item', 'menu']),
href: PropTypes.string,
content: PropTypes.string,
})),
logo: PropTypes.string,
logoAltText: PropTypes.string,
logoDestination: PropTypes.string,
avatar: PropTypes.string,
username: PropTypes.string,
loggedIn: PropTypes.bool,
actionRowContent: PropTypes.element,
// i18n
intl: intlShape.isRequired,
};
StudioDesktopHeaderBase.defaultProps = {
userMenu: [],
loggedOutItems: [],
logo: null,
logoAltText: null,
logoDestination: null,
avatar: null,
username: null,
loggedIn: false,
actionRowContent: null,
};
const StudioDesktopHeader = injectIntl(StudioDesktopHeaderBase);
const StudioHeader = ({ intl, actionRowContent }) => {
const { authenticatedUser, config } = useContext(AppContext);
const userMenu = authenticatedUser === null ? [] : [
{
type: 'item',
href: `${config.STUDIO_BASE_URL}`,
content: intl.formatMessage(messages['header.user.menu.studio.home']),
},
{
type: 'item',
href: `${config.STUDIO_BASE_URL}/maintenance`,
content: intl.formatMessage(messages['header.user.menu.studio.maintenance']),
},
{
type: 'item',
href: config.LOGOUT_URL,
content: intl.formatMessage(messages['header.user.menu.logout']),
},
];
const props = {
logo: config.LOGO_URL,
logoAltText: config.SITE_NAME,
logoDestination: config.STUDIO_BASE_URL,
loggedIn: authenticatedUser !== null,
username: authenticatedUser !== null ? authenticatedUser.username : null,
avatar: authenticatedUser !== null ? authenticatedUser.avatar : null,
actionRowContent,
userMenu,
loggedOutItems: [],
};
return <StudioDesktopHeader {...props} />;
};
StudioHeader.propTypes = {
intl: intlShape.isRequired,
actionRowContent: PropTypes.element,
};
StudioHeader.defaultProps = {
// eslint-disable-next-line react/jsx-no-useless-fragment
actionRowContent: <></>,
};
export default injectIntl(StudioHeader);

108
src/StudioHeader.test.jsx Normal file
View File

@@ -0,0 +1,108 @@
/* eslint-disable react/prop-types */
import React, { useMemo } from 'react';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import TestRenderer from 'react-test-renderer';
import { Link } from 'react-router-dom';
import { AppContext } from '@edx/frontend-platform/react';
import {
ActionRow,
Button,
Dropdown,
} from '@edx/paragon';
import { StudioHeader } from './index';
const StudioHeaderComponent = ({ contextValue, appMenu = null, mainMenu = [] }) => (
<IntlProvider locale="en" messages={{}}>
<AppContext.Provider
value={contextValue}
>
<StudioHeader appMenu={appMenu} mainMenu={mainMenu} />
</AppContext.Provider>
</IntlProvider>
);
const StudioHeaderContext = ({ actionRowContent = null }) => {
const headerContextValue = useMemo(() => ({
authenticatedUser: {
userId: 'abc123',
username: 'edX',
roles: [],
administrator: false,
},
config: {
STUDIO_BASE_URL: process.env.STUDIO_BASE_URL,
SITE_NAME: process.env.SITE_NAME,
LOGIN_URL: process.env.LOGIN_URL,
LOGOUT_URL: process.env.LOGOUT_URL,
LOGO_URL: process.env.LOGO_URL,
},
}), []);
return (
<IntlProvider locale="en" messages={{}}>
<AppContext.Provider
value={headerContextValue}
>
<StudioHeader actionRowContent={actionRowContent} />
</AppContext.Provider>
</IntlProvider>
);
};
describe('<StudioHeader />', () => {
it('renders correctly', () => {
const contextValue = {
authenticatedUser: {
userId: 'abc123',
username: 'edX',
roles: [],
administrator: false,
},
config: {
STUDIO_BASE_URL: process.env.STUDIO_BASE_URL,
SITE_NAME: process.env.SITE_NAME,
LOGIN_URL: process.env.LOGIN_URL,
LOGOUT_URL: process.env.LOGOUT_URL,
LOGO_URL: process.env.LOGO_URL,
},
};
const component = <StudioHeaderComponent contextValue={contextValue} />;
const wrapper = TestRenderer.create(component);
expect(wrapper.toJSON()).toMatchSnapshot();
});
it('renders correctly with optional action row content', () => {
const actionRowContent = (
<>
<Dropdown>
<Dropdown.Toggle variant="outline-primary" id="library-header-menu-dropdown">
Settings
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item as={Link} to="#">Dropdown Item 1</Dropdown.Item>
<Dropdown.Item as={Link} to="#">Dropdown Item 2</Dropdown.Item>
<Dropdown.Item as={Link} to="#">Dropdown Item 3</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<ActionRow.Spacer />
<Button
variant="tertiary"
href="#"
rel="noopener noreferrer"
target="_blank"
title="Help Button"
>Help
</Button>
</>
);
const component = <StudioHeaderContext actionRowContent={actionRowContent} />;
const wrapper = TestRenderer.create(component);
expect(wrapper.toJSON()).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,226 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<StudioHeader /> renders correctly 1`] = `
<header
className="site-header-desktop"
>
<a
className="nav-skip sr-only sr-only-focusable"
href="#main"
>
Skip to main content
</a>
<div
className="container-fluid null"
>
<div
className="nav-container position-relative d-flex align-items-center"
>
<img
alt="edX"
className="logo"
src="https://edx-cdn.org/v3/default/logo.svg"
/>
<div
className="pgn__action-row"
>
<nav
aria-label="Secondary"
className="nav secondary-menu-container align-items-center ml-auto"
>
<div
className="menu null"
onKeyDown={[Function]}
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
<button
aria-expanded={false}
aria-haspopup="menu"
aria-label="Account menu for edX"
className="menu-trigger btn btn-outline-primary d-inline-flex align-items-center pl-2 pr-3"
onClick={[Function]}
>
<span
className="avatar overflow-hidden d-inline-flex rounded-circle mr-2"
style={
Object {
"height": "1.5em",
"width": "1.5em",
}
}
>
<svg
aria-hidden={true}
focusable="false"
height="24px"
role="img"
style={
Object {
"height": "1.5em",
"width": "1.5em",
}
}
version="1.1"
viewBox="0 0 24 24"
width="24px"
>
<path
d="M4.10255106,18.1351061 C4.7170266,16.0581859 8.01891846,14.4720277 12,14.4720277 C15.9810815,14.4720277 19.2829734,16.0581859 19.8974489,18.1351061 C21.215206,16.4412566 22,14.3122775 22,12 C22,6.4771525 17.5228475,2 12,2 C6.4771525,2 2,6.4771525 2,12 C2,14.3122775 2.78479405,16.4412566 4.10255106,18.1351061 Z M12,24 C5.372583,24 0,18.627417 0,12 C0,5.372583 5.372583,0 12,0 C18.627417,0 24,5.372583 24,12 C24,18.627417 18.627417,24 12,24 Z M12,13 C9.790861,13 8,11.209139 8,9 C8,6.790861 9.790861,5 12,5 C14.209139,5 16,6.790861 16,9 C16,11.209139 14.209139,13 12,13 Z"
fill="currentColor"
/>
</svg>
</span>
edX
<svg
aria-hidden={true}
focusable="false"
height="16px"
role="img"
version="1.1"
viewBox="0 0 16 16"
width="16px"
>
<path
d="M7,4 L7,8 L11,8 L11,10 L5,10 L5,4 L7,4 Z"
fill="currentColor"
transform="translate(8.000000, 7.000000) rotate(-45.000000) translate(-8.000000, -7.000000) "
/>
</svg>
</button>
</div>
</nav>
</div>
</div>
</div>
</header>
`;
exports[`<StudioHeader /> renders correctly with optional action row content 1`] = `
<header
className="site-header-desktop"
>
<a
className="nav-skip sr-only sr-only-focusable"
href="#main"
>
Skip to main content
</a>
<div
className="container-fluid null"
>
<div
className="nav-container position-relative d-flex align-items-center"
>
<img
alt="edX"
className="logo"
src="https://edx-cdn.org/v3/default/logo.svg"
/>
<div
className="pgn__action-row"
>
<div
className="pgn__dropdown pgn__dropdown-light dropdown"
data-testid="dropdown"
>
<button
aria-expanded={false}
aria-haspopup={true}
className="dropdown-toggle btn btn-outline-primary"
disabled={false}
id="library-header-menu-dropdown"
onClick={[Function]}
type="button"
>
Settings
</button>
</div>
<span
className="pgn__action-row-spacer"
/>
<a
className="btn btn-tertiary"
href="#"
onClick={[Function]}
onKeyDown={[Function]}
rel="noopener noreferrer"
role="button"
target="_blank"
title="Help Button"
>
Help
</a>
<nav
aria-label="Secondary"
className="nav secondary-menu-container align-items-center ml-auto"
>
<div
className="menu null"
onKeyDown={[Function]}
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
<button
aria-expanded={false}
aria-haspopup="menu"
aria-label="Account menu for edX"
className="menu-trigger btn btn-outline-primary d-inline-flex align-items-center pl-2 pr-3"
onClick={[Function]}
>
<span
className="avatar overflow-hidden d-inline-flex rounded-circle mr-2"
style={
Object {
"height": "1.5em",
"width": "1.5em",
}
}
>
<svg
aria-hidden={true}
focusable="false"
height="24px"
role="img"
style={
Object {
"height": "1.5em",
"width": "1.5em",
}
}
version="1.1"
viewBox="0 0 24 24"
width="24px"
>
<path
d="M4.10255106,18.1351061 C4.7170266,16.0581859 8.01891846,14.4720277 12,14.4720277 C15.9810815,14.4720277 19.2829734,16.0581859 19.8974489,18.1351061 C21.215206,16.4412566 22,14.3122775 22,12 C22,6.4771525 17.5228475,2 12,2 C6.4771525,2 2,6.4771525 2,12 C2,14.3122775 2.78479405,16.4412566 4.10255106,18.1351061 Z M12,24 C5.372583,24 0,18.627417 0,12 C0,5.372583 5.372583,0 12,0 C18.627417,0 24,5.372583 24,12 C24,18.627417 18.627417,24 12,24 Z M12,13 C9.790861,13 8,11.209139 8,9 C8,6.790861 9.790861,5 12,5 C14.209139,5 16,6.790861 16,9 C16,11.209139 14.209139,13 12,13 Z"
fill="currentColor"
/>
</svg>
</span>
edX
<svg
aria-hidden={true}
focusable="false"
height="16px"
role="img"
version="1.1"
viewBox="0 0 16 16"
width="16px"
>
<path
d="M7,4 L7,8 L11,8 L11,10 L5,10 L5,4 L7,4 Z"
fill="currentColor"
transform="translate(8.000000, 7.000000) rotate(-45.000000) translate(-8.000000, -7.000000) "
/>
</svg>
</button>
</div>
</nav>
</div>
</div>
</div>
</header>
`;

View File

@@ -1,34 +1,28 @@
import arMessages from './messages/ar.json';
import caMessages from './messages/ca.json';
import heMessages from './messages/he.json';
import idMessages from './messages/id.json';
import plMessages from './messages/pl.json';
import ruMessages from './messages/ru.json';
import thMessages from './messages/th.json';
import ukMessages from './messages/uk.json';
// no need to import en messages-- they are in the defaultMessage field
import es419Messages from './messages/es_419.json';
import frMessages from './messages/fr.json';
import kokrMessages from './messages/ko_KR.json';
import ptbrMessages from './messages/pt_BR.json';
import es419Messages from './messages/es_419.json';
import zhcnMessages from './messages/zh_CN.json';
import ptMessages from './messages/pt.json';
import itMessages from './messages/it.json';
import ukMessages from './messages/uk.json';
import deMessages from './messages/de.json';
import ruMessages from './messages/ru.json';
import hiMessages from './messages/hi.json';
import frCAMessages from './messages/fr_CA.json';
// no need to import en messages-- they are in the defaultMessage field
const messages = {
ar: arMessages,
ca: caMessages,
he: heMessages,
id: idMessages,
pl: plMessages,
ru: ruMessages,
th: thMessages,
uk: ukMessages,
'es-419': es419Messages,
fr: frMessages,
'zh-cn': zhcnMessages,
'ko-kr': kokrMessages,
'pt-br': ptbrMessages,
pt: ptMessages,
it: itMessages,
de: deMessages,
hi: hiMessages,
'fr-ca': frCAMessages,
ru: ruMessages,
uk: ukMessages,
};
export default messages;

View File

@@ -1,30 +1,33 @@
{
"general.register.sentenceCase": "التسجيل",
"general.signIn.sentenceCase": "تسجيل الدخول",
"header.links.courses": "مساقات",
"header.links.programs": "برامج",
"header.links.content.search": "استكشف الجديد",
"header.links.schools": "المدارس والشركاء",
"header.links.courses": "المساقات",
"header.links.programs": "البرامج",
"header.links.content.search": "اكتشف الجديد",
"header.links.schools": "المدارس و الشركاء",
"header.user.menu.dashboard": "لوحة المعلومات",
"header.user.menu.profile": "الملف الشخصي",
"header.user.menu.account.settings": "حساب",
"header.user.menu.order.history": "سجل الطلبات",
"header.user.menu.account.settings": "الحساب",
"header.user.menu.order.history": "سجل الطلبيات",
"header.user.menu.logout": "تسجيل الخروج",
"header.user.menu.login": "تسجيل الدخول",
"header.user.menu.register": "تسجيل ",
"header.label.account.nav": "حساب",
"header.user.menu.register": "التسجيل",
"header.user.menu.studio.home": "صفحة الاستوديو الرئيسية",
"header.user.menu.studio.maintenance": "الصيانة",
"header.label.account.nav": "الحساب",
"header.label.account.menu": "قائمة الحساب",
"header.label.account.menu.for": "قائمة الحساب للمستخدم {username}",
"header.label.main.nav": "الرئيسية",
"header.label.account.menu.for": "قائمة حساب المستخدم {username}",
"header.label.main.nav": "القا|مة الرئيسية",
"header.label.main.menu": "القائمة الرئيسية",
"header.label.main.header": "الرئيسية",
"header.label.secondary.nav": "فرعي",
"header.label.secondary.nav": "القائمة الثانوية",
"header.label.skip.nav": "التخطي إلى المحتوى الرئيسي",
"header.label.app.nav": "تطبيق",
"header.menu.dashboard.label": "لوحة المعلومات",
"header.help.label": "مساعدة",
"header.help.label": "المساعدة",
"header.menu.profile.label": "الملف الشخصي",
"header.menu.account.label": "حساب",
"header.menu.orderHistory.label": "سجل الطلبات",
"header.menu.account.label": "الحساب",
"header.menu.orderHistory.label": "سجل الطلبيات",
"header.navigation.skipNavLink": "التخطي إلى المحتوى الرئيسي",
"header.menu.signOut.label": "تسجيل الخروج"
}

View File

@@ -1 +0,0 @@
{}

33
src/i18n/messages/de.json Normal file
View File

@@ -0,0 +1,33 @@
{
"general.register.sentenceCase": "Register",
"general.signIn.sentenceCase": "Sign in",
"header.links.courses": "Courses",
"header.links.programs": "Programs",
"header.links.content.search": "Discover New",
"header.links.schools": "Schools & Partners",
"header.user.menu.dashboard": "Dashboard",
"header.user.menu.profile": "Profile",
"header.user.menu.account.settings": "Account",
"header.user.menu.order.history": "Order History",
"header.user.menu.logout": "Logout",
"header.user.menu.login": "Login",
"header.user.menu.register": "Sign Up",
"header.user.menu.studio.home": "Studio Home",
"header.user.menu.studio.maintenance": "Maintenance",
"header.label.account.nav": "Account",
"header.label.account.menu": "Account Menu",
"header.label.account.menu.for": "Account menu for {username}",
"header.label.main.nav": "Main",
"header.label.main.menu": "Main Menu",
"header.label.main.header": "Main",
"header.label.secondary.nav": "Secondary",
"header.label.skip.nav": "Skip to main content",
"header.label.app.nav": "App",
"header.menu.dashboard.label": "Dashboard",
"header.help.label": "Help",
"header.menu.profile.label": "Profile",
"header.menu.account.label": "Account",
"header.menu.orderHistory.label": "Order History",
"header.navigation.skipNavLink": "Skip to main content.",
"header.menu.signOut.label": "Sign Out"
}

View File

@@ -12,6 +12,8 @@
"header.user.menu.logout": "Cerrar sesión",
"header.user.menu.login": "Login",
"header.user.menu.register": "Registrarse",
"header.user.menu.studio.home": "Inicio Studio",
"header.user.menu.studio.maintenance": "Mantenimiento",
"header.label.account.nav": "Cuenta",
"header.label.account.menu": "Menú de la cuenta",
"header.label.account.menu.for": "Menú de la cuenta para {username}",
@@ -20,6 +22,7 @@
"header.label.main.header": "Principal",
"header.label.secondary.nav": "Secondary",
"header.label.skip.nav": "Ir al contenido principal",
"header.label.app.nav": "Aplicación",
"header.menu.dashboard.label": "Panel de Control",
"header.help.label": "Ayuda",
"header.menu.profile.label": "Perfil",

View File

@@ -12,6 +12,8 @@
"header.user.menu.logout": "Déconnexion",
"header.user.menu.login": "Connexion",
"header.user.menu.register": "S'inscrire",
"header.user.menu.studio.home": "Accueil Studio",
"header.user.menu.studio.maintenance": "Maintenance",
"header.label.account.nav": "Compte",
"header.label.account.menu": "Menu du compte",
"header.label.account.menu.for": "Menu du compte pour {username}",
@@ -20,6 +22,7 @@
"header.label.main.header": "Principal",
"header.label.secondary.nav": "Secondaire",
"header.label.skip.nav": "Passer au contenu principal",
"header.label.app.nav": "Application",
"header.menu.dashboard.label": "Tableau de bord",
"header.help.label": "Aide",
"header.menu.profile.label": "Profil",

View File

@@ -12,6 +12,8 @@
"header.user.menu.logout": "Déconnexion",
"header.user.menu.login": "Connexion",
"header.user.menu.register": "S'inscrire",
"header.user.menu.studio.home": "Accueil Studio",
"header.user.menu.studio.maintenance": "Entretien",
"header.label.account.nav": "Compte",
"header.label.account.menu": "Menu de compte",
"header.label.account.menu.for": "Menu de compte pour {username}",
@@ -20,6 +22,7 @@
"header.label.main.header": "Principal",
"header.label.secondary.nav": "Secondaire",
"header.label.skip.nav": "Passer au contenu de cette vue",
"header.label.app.nav": "Application",
"header.menu.dashboard.label": "Tableau de bord",
"header.help.label": "Aide",
"header.menu.profile.label": "Profil",

View File

@@ -1 +0,0 @@
{}

33
src/i18n/messages/hi.json Normal file
View File

@@ -0,0 +1,33 @@
{
"general.register.sentenceCase": "Register",
"general.signIn.sentenceCase": "Sign in",
"header.links.courses": "Courses",
"header.links.programs": "Programs",
"header.links.content.search": "Discover New",
"header.links.schools": "Schools & Partners",
"header.user.menu.dashboard": "Dashboard",
"header.user.menu.profile": "Profile",
"header.user.menu.account.settings": "Account",
"header.user.menu.order.history": "Order History",
"header.user.menu.logout": "Logout",
"header.user.menu.login": "Login",
"header.user.menu.register": "Sign Up",
"header.user.menu.studio.home": "Studio Home",
"header.user.menu.studio.maintenance": "Maintenance",
"header.label.account.nav": "Account",
"header.label.account.menu": "Account Menu",
"header.label.account.menu.for": "Account menu for {username}",
"header.label.main.nav": "Main",
"header.label.main.menu": "Main Menu",
"header.label.main.header": "Main",
"header.label.secondary.nav": "Secondary",
"header.label.skip.nav": "Skip to main content",
"header.label.app.nav": "App",
"header.menu.dashboard.label": "Dashboard",
"header.help.label": "Help",
"header.menu.profile.label": "Profile",
"header.menu.account.label": "Account",
"header.menu.orderHistory.label": "Order History",
"header.navigation.skipNavLink": "Skip to main content.",
"header.menu.signOut.label": "Sign Out"
}

View File

@@ -1 +0,0 @@
{}

33
src/i18n/messages/it.json Normal file
View File

@@ -0,0 +1,33 @@
{
"general.register.sentenceCase": "Register",
"general.signIn.sentenceCase": "Sign in",
"header.links.courses": "Courses",
"header.links.programs": "Programs",
"header.links.content.search": "Discover New",
"header.links.schools": "Schools & Partners",
"header.user.menu.dashboard": "Dashboard",
"header.user.menu.profile": "Profile",
"header.user.menu.account.settings": "Account",
"header.user.menu.order.history": "Order History",
"header.user.menu.logout": "Logout",
"header.user.menu.login": "Login",
"header.user.menu.register": "Sign Up",
"header.user.menu.studio.home": "Studio Home",
"header.user.menu.studio.maintenance": "Maintenance",
"header.label.account.nav": "Account",
"header.label.account.menu": "Account Menu",
"header.label.account.menu.for": "Account menu for {username}",
"header.label.main.nav": "Main",
"header.label.main.menu": "Main Menu",
"header.label.main.header": "Main",
"header.label.secondary.nav": "Secondary",
"header.label.skip.nav": "Skip to main content",
"header.label.app.nav": "App",
"header.menu.dashboard.label": "Dashboard",
"header.help.label": "Help",
"header.menu.profile.label": "Profile",
"header.menu.account.label": "Account",
"header.menu.orderHistory.label": "Order History",
"header.navigation.skipNavLink": "Skip to main content.",
"header.menu.signOut.label": "Sign Out"
}

View File

@@ -1,2 +0,0 @@
{
}

View File

@@ -1 +0,0 @@
{}

33
src/i18n/messages/pt.json Normal file
View File

@@ -0,0 +1,33 @@
{
"general.register.sentenceCase": "Register",
"general.signIn.sentenceCase": "Sign in",
"header.links.courses": "Courses",
"header.links.programs": "Programs",
"header.links.content.search": "Discover New",
"header.links.schools": "Schools & Partners",
"header.user.menu.dashboard": "Dashboard",
"header.user.menu.profile": "Profile",
"header.user.menu.account.settings": "Account",
"header.user.menu.order.history": "Order History",
"header.user.menu.logout": "Logout",
"header.user.menu.login": "Login",
"header.user.menu.register": "Sign Up",
"header.user.menu.studio.home": "Studio Home",
"header.user.menu.studio.maintenance": "Maintenance",
"header.label.account.nav": "Account",
"header.label.account.menu": "Account Menu",
"header.label.account.menu.for": "Account menu for {username}",
"header.label.main.nav": "Main",
"header.label.main.menu": "Main Menu",
"header.label.main.header": "Main",
"header.label.secondary.nav": "Secondary",
"header.label.skip.nav": "Skip to main content",
"header.label.app.nav": "App",
"header.menu.dashboard.label": "Dashboard",
"header.help.label": "Help",
"header.menu.profile.label": "Profile",
"header.menu.account.label": "Account",
"header.menu.orderHistory.label": "Order History",
"header.navigation.skipNavLink": "Skip to main content.",
"header.menu.signOut.label": "Sign Out"
}

View File

@@ -1,2 +0,0 @@
{
}

View File

@@ -1 +1,33 @@
{}
{
"general.register.sentenceCase": "Register",
"general.signIn.sentenceCase": "Sign in",
"header.links.courses": "Courses",
"header.links.programs": "Programs",
"header.links.content.search": "Discover New",
"header.links.schools": "Schools & Partners",
"header.user.menu.dashboard": "Dashboard",
"header.user.menu.profile": "Profile",
"header.user.menu.account.settings": "Account",
"header.user.menu.order.history": "Order History",
"header.user.menu.logout": "Logout",
"header.user.menu.login": "Login",
"header.user.menu.register": "Sign Up",
"header.user.menu.studio.home": "Studio Home",
"header.user.menu.studio.maintenance": "Maintenance",
"header.label.account.nav": "Account",
"header.label.account.menu": "Account Menu",
"header.label.account.menu.for": "Account menu for {username}",
"header.label.main.nav": "Main",
"header.label.main.menu": "Main Menu",
"header.label.main.header": "Main",
"header.label.secondary.nav": "Secondary",
"header.label.skip.nav": "Skip to main content",
"header.label.app.nav": "App",
"header.menu.dashboard.label": "Dashboard",
"header.help.label": "Help",
"header.menu.profile.label": "Profile",
"header.menu.account.label": "Account",
"header.menu.orderHistory.label": "Order History",
"header.navigation.skipNavLink": "Skip to main content.",
"header.menu.signOut.label": "Sign Out"
}

View File

@@ -1 +0,0 @@
{}

View File

@@ -1 +1,33 @@
{}
{
"general.register.sentenceCase": "Register",
"general.signIn.sentenceCase": "Увійти",
"header.links.courses": "Курси",
"header.links.programs": "Програми",
"header.links.content.search": "Discover New",
"header.links.schools": "Schools & Partners",
"header.user.menu.dashboard": "Dashboard",
"header.user.menu.profile": "Profile",
"header.user.menu.account.settings": "Account",
"header.user.menu.order.history": "Order History",
"header.user.menu.logout": "Logout",
"header.user.menu.login": "Login",
"header.user.menu.register": "Sign Up",
"header.user.menu.studio.home": "Studio Home",
"header.user.menu.studio.maintenance": "Maintenance",
"header.label.account.nav": "Account",
"header.label.account.menu": "Меню облікового запису",
"header.label.account.menu.for": "Меню облікового запису для {username}",
"header.label.main.nav": "Main",
"header.label.main.menu": "Main Menu",
"header.label.main.header": "Main",
"header.label.secondary.nav": "Secondary",
"header.label.skip.nav": "Перейти до головного змісту",
"header.label.app.nav": "App",
"header.menu.dashboard.label": "Dashboard",
"header.help.label": "Help",
"header.menu.profile.label": "Profile",
"header.menu.account.label": "Account",
"header.menu.orderHistory.label": "Order History",
"header.navigation.skipNavLink": "Перейти до головного змісту.",
"header.menu.signOut.label": "Sign Out"
}

View File

@@ -12,6 +12,8 @@
"header.user.menu.logout": "Logout",
"header.user.menu.login": "Login",
"header.user.menu.register": "Sign Up",
"header.user.menu.studio.home": "Studio Home",
"header.user.menu.studio.maintenance": "Maintenance",
"header.label.account.nav": "Account",
"header.label.account.menu": "Account Menu",
"header.label.account.menu.for": "Account menu for {username}",
@@ -20,6 +22,7 @@
"header.label.main.header": "Main",
"header.label.secondary.nav": "Secondary",
"header.label.skip.nav": "Skip to main content",
"header.label.app.nav": "App",
"header.menu.dashboard.label": "Dashboard",
"header.help.label": "Help",
"header.menu.profile.label": "Profile",

View File

@@ -1,7 +1,8 @@
import Header from './Header';
import LearningHeader from './learning-header/LearningHeader';
import messages from './i18n/index';
import StudioHeader from './StudioHeader';
export { LearningHeader, messages };
export { LearningHeader, messages, StudioHeader };
export default Header;

View File

@@ -27,7 +27,7 @@ $white: #fff;
.learning-header {
min-width: 0;
.course-title-lockup {
min-width: 0;

View File

@@ -7,25 +7,23 @@ import { Button } from '@edx/paragon';
import genericMessages from '../generic/messages';
function AnonymousUserMenu({ intl }) {
return (
<div>
<Button
className="mr-3"
variant="outline-primary"
href={`${getConfig().LMS_BASE_URL}/register?next=${encodeURIComponent(global.location.href)}`}
>
{intl.formatMessage(genericMessages.registerSentenceCase)}
</Button>
<Button
variant="primary"
href={`${getLoginRedirectUrl(global.location.href)}`}
>
{intl.formatMessage(genericMessages.signInSentenceCase)}
</Button>
</div>
);
}
const AnonymousUserMenu = ({ intl }) => (
<div>
<Button
className="mr-3"
variant="outline-primary"
href={`${getConfig().LMS_BASE_URL}/register?next=${encodeURIComponent(global.location.href)}`}
>
{intl.formatMessage(genericMessages.registerSentenceCase)}
</Button>
<Button
variant="primary"
href={`${getLoginRedirectUrl(global.location.href)}`}
>
{intl.formatMessage(genericMessages.signInSentenceCase)}
</Button>
</div>
);
AnonymousUserMenu.propTypes = {
intl: intlShape.isRequired,

View File

@@ -3,14 +3,13 @@ import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faUserCircle } from '@fortawesome/free-solid-svg-icons';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { Dropdown } from '@edx/paragon';
import messages from './messages';
function AuthenticatedUserDropdown({ intl, username }) {
const AuthenticatedUserDropdown = ({ intl, username }) => {
const dashboardMenuItem = (
<Dropdown.Item href={`${getConfig().LMS_BASE_URL}/dashboard`}>
{intl.formatMessage(messages.dashboard)}
@@ -19,8 +18,8 @@ function AuthenticatedUserDropdown({ intl, username }) {
return (
<>
<a className="text-gray-700 mr-3" href={`${getConfig().SUPPORT_URL}`}>{intl.formatMessage(messages.help)}</a>
<Dropdown className="user-dropdown">
<a className="text-gray-700" href={`${getConfig().SUPPORT_URL}`}>{intl.formatMessage(messages.help)}</a>
<Dropdown className="user-dropdown ml-3">
<Dropdown.Toggle variant="outline-primary">
<FontAwesomeIcon icon={faUserCircle} className="d-md-none" size="lg" />
<span data-hj-suppress className="d-none d-md-inline">
@@ -29,10 +28,10 @@ function AuthenticatedUserDropdown({ intl, username }) {
</Dropdown.Toggle>
<Dropdown.Menu className="dropdown-menu-right">
{dashboardMenuItem}
<Dropdown.Item href={`${getConfig().LMS_BASE_URL}/u/${username}`}>
<Dropdown.Item href={`${getConfig().ACCOUNT_PROFILE_URL}/u/${username}`}>
{intl.formatMessage(messages.profile)}
</Dropdown.Item>
<Dropdown.Item href={`${getConfig().LMS_BASE_URL}/account/settings`}>
<Dropdown.Item href={getConfig().ACCOUNT_SETTINGS_URL}>
{intl.formatMessage(messages.account)}
</Dropdown.Item>
{ getConfig().ORDER_HISTORY_URL && (
@@ -47,7 +46,7 @@ function AuthenticatedUserDropdown({ intl, username }) {
</Dropdown>
</>
);
}
};
AuthenticatedUserDropdown.propTypes = {
intl: intlShape.isRequired,

View File

@@ -8,18 +8,16 @@ import AnonymousUserMenu from './AnonymousUserMenu';
import AuthenticatedUserDropdown from './AuthenticatedUserDropdown';
import messages from './messages';
function LinkedLogo({
const LinkedLogo = ({
href,
src,
alt,
...attributes
}) {
return (
<a href={href} {...attributes}>
<img className="d-block" src={src} alt={alt} />
</a>
);
}
}) => (
<a href={href} {...attributes}>
<img className="d-block" src={src} alt={alt} />
</a>
);
LinkedLogo.propTypes = {
href: PropTypes.string.isRequired,
@@ -27,9 +25,9 @@ LinkedLogo.propTypes = {
alt: PropTypes.string.isRequired,
};
function LearningHeader({
const LearningHeader = ({
courseOrg, courseNumber, courseTitle, intl, showUserDropdown,
}) {
}) => {
const { authenticatedUser } = useContext(AppContext);
const headerLogo = (
@@ -51,17 +49,17 @@ function LearningHeader({
<span className="d-block m-0 font-weight-bold course-title">{courseTitle}</span>
</div>
{showUserDropdown && authenticatedUser && (
<AuthenticatedUserDropdown
username={authenticatedUser.username}
/>
<AuthenticatedUserDropdown
username={authenticatedUser.username}
/>
)}
{showUserDropdown && !authenticatedUser && (
<AnonymousUserMenu />
<AnonymousUserMenu />
)}
</div>
</header>
);
}
};
LearningHeader.propTypes = {
courseOrg: PropTypes.string,

View File

@@ -12,7 +12,7 @@ describe('Header', () => {
it('displays user button', () => {
render(<Header />);
expect(screen.getByRole('button')).toHaveTextContent(authenticatedUser.username);
expect(screen.getByText(authenticatedUser.username)).toBeInTheDocument();
});
it('displays course data', () => {

View File

@@ -3,7 +3,7 @@
import Enzyme from 'enzyme';
import React from 'react';
import PropTypes from 'prop-types';
import Adapter from 'enzyme-adapter-react-16';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import '@testing-library/jest-dom';
import '@testing-library/jest-dom/extend-expect';
import 'babel-polyfill';
@@ -22,6 +22,8 @@ Enzyme.configure({ adapter: new Adapter() });
// These configuration values are usually set in webpack's EnvironmentPlugin however
// Jest does not use webpack so we need to set these so for testing
process.env.ACCESS_TOKEN_COOKIE_NAME = 'edx-jwt-cookie-header-payload';
process.env.ACCOUNT_PROFILE_URL = 'http://localhost:1995';
process.env.ACCOUNT_SETTINGS_URL = 'http://localhost:1997';
process.env.BASE_URL = 'localhost:1995';
process.env.CREDENTIALS_BASE_URL = 'http://localhost:18150';
process.env.CSRF_TOKEN_API_PATH = '/csrf/api/v1/token';
@@ -102,16 +104,14 @@ function render(
...renderOptions
} = {},
) {
function Wrapper({ children }) {
return (
const Wrapper = ({ children }) => (
// eslint-disable-next-line react/jsx-filename-extension
<IntlProvider locale="en">
<AppProvider store={store}>
{children}
</AppProvider>
</IntlProvider>
);
}
<IntlProvider locale="en">
<AppProvider store={store}>
{children}
</AppProvider>
</IntlProvider>
);
Wrapper.propTypes = {
children: PropTypes.node.isRequired,

6
src/test-utils.js Normal file
View File

@@ -0,0 +1,6 @@
const executeThunk = async (thunk, dispatch, getState) => {
await thunk(dispatch, getState);
await new Promise(setImmediate);
};
export default executeThunk;