Compare commits

...

1950 Commits

Author SHA1 Message Date
dependabot[bot]
dbaf48202a chore(deps): bump minimatch and eslint-plugin-formatjs
Bumps [minimatch](https://github.com/isaacs/minimatch) and [eslint-plugin-formatjs](https://github.com/formatjs/formatjs). These dependencies needed to be updated together.

Updates `minimatch` from 9.0.5 to 9.0.9
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v9.0.5...v9.0.9)

Updates `minimatch` from 5.1.6 to 5.1.9
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v9.0.5...v9.0.9)

Updates `minimatch` from 3.1.2 to 3.1.5
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v9.0.5...v9.0.9)

Updates `eslint-plugin-formatjs` from 4.13.3 to 4.14.0
- [Release notes](https://github.com/formatjs/formatjs/releases)
- [Commits](https://github.com/formatjs/formatjs/compare/eslint-plugin-formatjs@4.13.3...eslint-plugin-formatjs@4.14.0)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 9.0.9
  dependency-type: indirect
- dependency-name: minimatch
  dependency-version: 5.1.9
  dependency-type: indirect
- dependency-name: minimatch
  dependency-version: 3.1.5
  dependency-type: indirect
- dependency-name: eslint-plugin-formatjs
  dependency-version: 4.14.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-27 17:14:15 +00:00
Braden MacDonald
af204c78a5 test: run only oxlint, not eslint (#2909) 2026-02-27 09:12:24 -08:00
Rômulo Penido
2e6209314f feat: add fullscreen button to XBlock editor (#2892) 2026-02-27 10:05:14 -05:00
Navin Karkera
060f7d4618 refactor(course-outline): replace thunks with react query, add typed APIs, and improve type usages (#2900)
* Replaces configure xblock and section highlights redux functions with react-query.
* Replaces section highlights thunks with react query
* Replaces duplicate block thunks
* Removes add subsection, unit redux functions
* Replaces scrollTo redux state to react-query based state.
* Replaces paste unit block redux functions
* Removes a lot of redux related functions as a result.
* Reduces API calls without compromising data integrity.
2026-02-27 09:23:46 -05:00
Chris Chávez
815b80a944 refactor: Migrate advancedSettings from the redux store to React Query (#2893) 2026-02-26 23:17:57 +00:00
Bryann Valderrama
e8cd7c2dcc feat: add team groups section in group configurations (#1728) 2026-02-26 14:02:31 -08:00
Chris Chávez
c4a09a2b43 refactor: Migrate courseImport from redux store to React query (#2902) 2026-02-26 14:34:13 -05:00
Areeb Sajjad
3599630cd7 fix: allow configure modal overflow to prevent datepicker clipping (#2901) 2026-02-25 17:19:18 -08:00
Chris Chávez
56726448fc Refactor: Move courseTeam from redux store to react query (#2888)
* refactor: Move `courseTeam` from redux store to react query

* fix: Broken types

* fix: Show user readable error

* fix: Broken coverage

* fix: Broken coverage

* refactor: Add default message error
2026-02-24 10:11:36 -05:00
renovate[bot]
b57386b9b6 chore(deps): update dependency oxlint-tsgolint to ^0.14.0 (#2896)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-23 22:46:26 +00:00
renovate[bot]
e9bf4566de chore(deps): update dependency @types/lodash to v4.17.24 (#2897)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-23 21:09:45 +00:00
edX requirements bot
1324b33789 chore: update browserslist DB (#2899)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2026-02-23 21:09:26 +00:00
Taylor Payne
b256036527 fix: correct typos in user-facing messages (#2894) 2026-02-21 11:43:13 -08:00
Navin Karkera
ee6006e0e3 refactor(course-outline): improve query cache handling and remove redux thunks (#2884)
- Centralizes and reuses query cache handling logic:
Introduces a `ParentIds` type (src/generic/types.ts) and standardizes its use across data/API hooks for updating or invalidating parent/child query caches.
- Ensures cache coherence using `cancelQueries` before updating query data:
Before calling `setQueryData` for any block, any inflight queries are cancelled to prevent race conditions and stale UI.
- Simplifies post-sync/invalidation flows:
Removes Redux thunk usages in favor of direct query invalidations using React Query APIs within course outline cards, sidebars, publish modal, and `unlinkmodal`.
- Refactors data types for clarity:
Splits XBlock into `XBlockBase` and derived interfaces so the presence of `childInfo` is explicit.
- Cleans up redundant code and props:
Removes unnecessary `memoization`, `useDispatch` imports, and duplicate logic in React components.
2026-02-20 13:10:28 -05:00
MuPp3t33r
8f8c6d8dd2 refactor: update relative path to absolute path alias (#2891) 2026-02-20 09:10:25 -08:00
Chris Chávez
7c1eb59f18 feat: Make selectable component cards & Component Info Sidebar [FC-0114] (#2880)
- Changes in the Unit sidebar context to enable selected components
- Implements the component info sidebar.
- Implements the container/component selection when opening the align sidebar
2026-02-19 17:02:26 -05:00
Rodrigo Mendez
5ccf39d130 feat: Add validation for Advanced Settings permissions using openedx-authz (#2869)
* feat: Add validation for Advanced Settings permissions using openedx-authz

* squash!: Increase test coverage

* squash!: Fix lint issues

* squash!: Validate advanced settings permission on HelpSidebar

* squash!: Increase test coverage

* squash!: Attend PR comments
2026-02-19 14:39:04 -06:00
Chris Chávez
42f26e7404 refactor: Move redux to react query in course checklist (#2870) 2026-02-19 13:10:18 -05:00
renovate[bot]
01ddf0d2ad chore(deps): update dependency @edx/frontend-platform to v8.5.5 (#2882)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-18 23:20:06 +00:00
renovate[bot]
7a8b4ced01 chore(deps): update dependency fast-xml-parser to v5.3.6 [security] (#2886)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-18 23:18:47 +00:00
Muhammad Faraz Maqsood
e116e10845 fix: localize rerun button text (#2887)
* fix: localize rerun button text

* chore: use <FormattedMessage /> instead of formatMessage()

---------

Co-authored-by: Muhammad Faraz  Maqsood <faraz.maqsood@A006-01130.local>
Co-authored-by: Braden MacDonald <braden@opencraft.com>
2026-02-18 22:58:12 +00:00
MuPp3t33r
0b357a1be1 fix: Replace duplicate hardcoded max file size with constant (#2875) 2026-02-18 14:26:08 -08:00
edX requirements bot
e281681168 chore: update browserslist DB (#2881)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2026-02-16 00:32:33 +00:00
Chris Chávez
c39923fc81 fix: Nits on UX/UI in the new sidebars in course outline and unit page [FC-0114] (#2871)
- Fixes the open nits/issues listed in https://github.com/openedx/frontend-app-authoring/issues/2868
- Fixes the small nit in the back button in the import workflow: https://github.com/openedx/frontend-app-authoring/issues/2524#issuecomment-3849649651
- Fixes the small nit in the unsupported text in the import workflow: https://github.com/openedx/frontend-app-authoring/issues/2525#issuecomment-3862737018. This fix depends on https://github.com/openedx/openedx-platform/pull/38005
2026-02-13 15:09:28 -05:00
Chris Chávez
4d401a9c22 feat: Unit align sidebar [FC-0114] (#2856)
Implements the align sidebar in the unit page for the unit and components
2026-02-13 15:07:53 -05:00
renovate[bot]
72421969d9 chore(deps): update dependency @tanstack/react-query to v5.90.21 (#2858)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-13 14:28:28 -05:00
renovate[bot]
0aad03420b chore(deps): update codemirror (#2857)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-13 19:28:19 +00:00
renovate[bot]
45811ce6de chore(deps): update dependency fast-xml-parser to v5.3.5 (#2867)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-13 11:14:30 -08:00
renovate[bot]
d1c3fb96de chore(deps): update dependency @types/react to v18.3.28 (#2866)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-09 10:38:36 -08:00
Chris Chávez
2d5421e09f feat: Unit Add sidebar [FC-0114] (#2837)
Implements the new Unit add Sidebar
2026-02-09 13:17:04 -05:00
Chris Chávez
a16087a1d0 fix: Nits on the style of library icon [FC-0114] (#2863) 2026-02-09 11:59:24 -05:00
Navin Karkera
bb6b2ab33c feat: container info sidebar and add sidebar updates (#2830)
* Adds section, subsection and unit sidebar info tab in course outline as described in https://github.com/openedx/frontend-app-authoring/issues/2638
* Updates the sidebar design and behaviour as per https://github.com/openedx/frontend-app-authoring/issues/2826
* Updates course outline to use react query and removes redux store usage as much as possible. Updated parts that require absolutely cannot work without redux without heavy refactoring (will require quiet some time) to work in tandem with react-query.
2026-02-09 11:03:27 -05:00
renovate[bot]
eae178a9ec chore(deps): update dependency lodash to v4.17.23 [security] (#2861)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-09 00:44:37 +00:00
edX requirements bot
2ab1219f36 chore: update browserslist DB (#2865)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2026-02-09 00:28:05 +00:00
Rômulo Penido
7173b71cc4 fix: update sidebar design (#2852) 2026-02-05 15:44:46 -05:00
Brian Smith
f900ace15c chore(deps): regenerate package-lock.json (#2862)
Co-authored-by: Claude Code <noreply@anthropic.com>
2026-02-02 13:58:30 -08:00
Braden MacDonald
d44425c68f test: lint using oxlint as well as eslint (#2847)
PR enables the use of oxlint (type-aware) alongside eslint, on a trial basis. Oxlint supports most of the same rules, plus more, is eslint compatible, and is much, much faster.
2026-02-02 11:47:31 -05:00
Braden MacDonald
6effb4d39e chore: fix various lint/type issues found by oxlint (#2850) 2026-01-31 01:01:11 +00:00
Rômulo Penido
b0066e547c feat: create context for sidebarPages (#2827)
Creates the `OutlineSidebarPagesContext` so we can add new pages using plugins, as in https://github.com/openedx/frontend-plugin-aspects/pull/115
2026-01-30 17:52:52 -05:00
Rômulo Penido
6558c2b1ed fix: access restricted label refresh (#2846) 2026-01-30 17:09:42 -05:00
Braden MacDonald
747c2bc1b0 chore: clean up ValidationResult for NumericalInput problems (#2849) 2026-01-29 09:48:40 -08:00
Braden MacDonald
27e709912d fix: don't use eval() to parse OLX (#2848) 2026-01-29 10:39:48 -05:00
Braden MacDonald
9d9d7a7167 fix: resolve incorrect or missing 'await' usages (#2592)
* chore: fix incorrect or missing 'await' usages
* test: fix broken test
* chore: ignore lines causing patch coverage to fail
2026-01-28 16:48:13 -08:00
renovate[bot]
7e53e1143f chore(deps): update codemirror (#2840)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-28 16:32:53 -08:00
renovate[bot]
66656753b4 fix(deps): update dependency @edx/browserslist-config to v1.5.1 (#2844)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-28 10:41:07 -08:00
Irtaza Akram
05de984fa4 fix: show deafult grading method 2026-01-28 08:57:04 -05:00
Irtaza Akram
f6da58a950 fix: test 2026-01-28 08:57:04 -05:00
Irtaza Akram
5e5c92f487 fix: type error 2026-01-28 08:57:04 -05:00
Irtaza Akram
10705bc921 fix: test failures 2026-01-28 08:57:04 -05:00
Irtaza Akram
2e836a55cf fix: add grading method view 2026-01-28 08:57:04 -05:00
Braden MacDonald
292a457834 chore: rename more files from .js to .ts (#2842)
* chore: rename more files from .js to .ts

* fix: fix some little issues caught by TS

* fix: fix type of 'certificateId'
2026-01-27 13:16:47 -08:00
renovate[bot]
5d97a98294 chore(deps): update dependency @edx/frontend-platform to v8.5.4 (#2838)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-26 17:46:53 -08:00
renovate[bot]
53923d0db4 chore(deps): update dependency @testing-library/react to v16.3.2 (#2841)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-26 15:44:27 -08:00
Chris Chávez
5157cbcfb2 feat: New Unit info sidebar [FC-0114] (#2822)
- Implements the basics for the Unit Sidebar:
    - Splits the sidebar in legacy sidebar and in the new sidebar
- Implements the Unit Info Sidebar:
    - Implements a new design for the visibility and publish status card.
    - Implements the new Visibility field.
    - Implements the settings tab for the sidebar. Implements all the new form to edit the 
      settings in the sidebar.
2026-01-26 16:18:32 -05:00
Chris Chávez
ef93e95dd7 feat: New header in course unit page [FC-0114] (#2751)
- `ENABLE_UNIT_PAGE_NEW_DESIGN` flag created
- New Status Bard implemented in the header of the course unit page.
- New buttons added in the header of the course unit page.
- Which user roles will this change impact? "Course Author".
2026-01-26 12:52:50 -05:00
Braden MacDonald
1626d6808d chore: rename all 'messages.js' to 'messages.ts' (#2836) 2026-01-26 12:22:09 -05:00
edX requirements bot
b1c3151ca1 chore: update browserslist DB (#2839)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2026-01-26 00:24:23 +00:00
renovate[bot]
bea1619537 chore(deps): update dependency @openedx/paragon to v23.19.1 (#2765)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-23 23:00:25 +00:00
Navin Karkera
89e327b633 feat: course outline header update [FC-0114] (#2823)
Modifies new course outline header and actions
2026-01-23 09:08:19 -05:00
Braden MacDonald
0db79f3527 fix: clean up invalid breadcrumb usages in library updates (#2811) 2026-01-22 09:45:34 -08:00
Chris Chávez
82e24193a8 refactor: Use preview migration API & feat: Block import when the import would exceed the block limit [FC-0112] (#2700)
- Use the new preview migration API implemented in https://github.com/openedx/edx-platform/pull/37818
- Clean the code for the preview.
- Implements the commented in https://github.com/openedx/frontend-app-authoring/issues/2525#issuecomment-3554310315
2026-01-20 14:44:35 -05:00
renovate[bot]
f57d33a74e chore(deps): update react-router monorepo to v6.30.3 (#2819)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-19 16:35:50 -08:00
Chris Chávez
0b2b8e142c feat: New align sidebar for Course Outline [FC-0114] (#2812)
- Adds the align sidebar for Course and Section/Subsection/Unit cards (https://github.com/openedx/frontend-app-authoring/issues/2625)
- Add a new library lock icon to tags imported from upstream (https://github.com/openedx/frontend-app-authoring/issues/2234)
2026-01-19 11:59:43 -05:00
edX requirements bot
d5352b8632 chore: update browserslist DB (#2828)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2026-01-19 00:24:56 +00:00
Chris Chávez
3076dc7598 fix: Bug when adding spaces to containers names in course outline (#2825)
- Fixes the bug introduced in https://github.com/openedx/frontend-app-authoring/pull/2732
- Removes the unnecessary `preventDefault`
2026-01-15 09:12:35 -05:00
Navin Karkera
a23a4da0a2 feat: add content in location in course outline [FC-0114] (#2820)
- Add container in-location in course outline using new add sidebar.
- Creates the placeholder card while creating a container
2026-01-15 07:29:26 -05:00
Chris Chávez
4cda17e046 feat: Make sections/subsections/units selectable in course outline [FC-0114] (#2732) 2026-01-12 21:12:46 -05:00
renovate[bot]
969f7a2858 chore(deps): update dependency @types/lodash to v4.17.23 (#2818)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-12 09:47:14 -08:00
edX requirements bot
12f1c2b1f5 chore: update browserslist DB (#2817)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2026-01-12 00:26:34 +00:00
Muhammad Anas
6464f37e2a feat: plugin slot for marketing banner on Schedule & Details page (#2748)
* feat: add Page Banner Slot for Schedule and Details Page

* fix: js to ts

* fix: remove js

* fix: lint issues

* fix: issues

* fix: lint issues

* fix: issues

* fix: issue

* fix: issue
2026-01-09 15:21:12 -08:00
renovate[bot]
5641daf68d chore(deps): update dependency react-responsive to v10 (#2784)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-09 11:16:35 -08:00
Navin Karkera
3c22e4bbe1 feat: Add sidebar and library dropdown filter [FC-0114] (#2778)
* Add flow in course outline sidebar. Allows author to add new section/subsection/unit or any container from existing libraries via sidebar.
* Adds library dropdown filter and collections dropdown filter in add sidebar. Allows authors to filter containers by selected libraries and collections.
2026-01-09 12:14:48 -05:00
renovate[bot]
a7cbfead75 chore(deps): update codemirror to v6.5.3 (#2771)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-09 00:52:38 +00:00
renovate[bot]
7b0223cefc chore(deps): update dependency @tanstack/react-query to v5.90.16 (#2781)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-08 16:39:20 -08:00
renovate[bot]
478749028b chore(deps): update dependency @testing-library/react to v16.3.1 (#2770)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-07 09:49:31 -08:00
Rômulo Penido
220924233e feat: course outline sidebar (#2731)
implements the new sidebar design for the Course Outline
2026-01-06 08:13:25 -05:00
edX requirements bot
122414cb73 chore: update browserslist DB (#2780)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2026-01-05 00:25:41 +00:00
Rômulo Penido
fd0395ba03 fix: make sidebar (and content) fill the whole page (#2777) 2025-12-31 18:15:47 -05:00
Navin Karkera
38dfb68286 refactor: course import analysis and details page in libraries (#2774)
* Updates analysis details body text
* Updates partial banner text
* Rounds percentage of supported blocks
* Removes unsupported children blocks from total counts and percentages.
* Updates spacing in analysis page.
2025-12-31 10:36:44 -05:00
Navin Karkera
0f20267cc4 feat: course import filter in library and fix list order (#2773)
* Adds filter to show/hide previously imported courses in course import page in libraries.
* Fix issue with ordering of courses listing.
2025-12-29 09:37:44 -05:00
Rômulo Penido
7f10575b52 fix: import summary text (#2772)
Updates the text on the import summary shown on partial imports.
2025-12-24 12:28:31 -05:00
Chris Chávez
ef6bd073c0 refactor: Migrate accessibilityPage variable in Redux store to React Query (#2760) 2025-12-23 09:18:13 -05:00
Navin Karkera
f4d20eba45 feat: bulk update legacy library references (#2764)
Shows an alert in course outline and review tab of course libraries page when the course contains legacy library content blocks that depend on libraries that are already migrated to library v2, i.e. the blocks are ready to be converted into item banks that can make use of these new v2 libraries.
Authors can click on a single button to convert all references in a single go. The button launches a background task which is then polled by the frontend and the status is presented to the Author.
2025-12-22 12:54:54 -05:00
edX requirements bot
68a4b04475 chore: update browserslist DB (#2769)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-12-22 00:24:49 +00:00
Diana Villalvazo
c2592a7e6e Add external links override support (#2730)
* feat: add external links override support

* fix: add note, fix 404 url and fix unrelated typo

* test: fix
2025-12-19 13:06:03 -06:00
Jesus Balderrama
9072bb66b7 feat: better validation for NumericalInput problem editor (#2615)
* feat(form): add validation to NumericalInput to accept only numeric values

* style(format): fix spaces and update message to camelCase

* fix(content): update text for clarity

Co-authored-by: Kyle McCormick <kyle@kylemccormick.me>

* feat(validation): validation added to numeric input with new endpoint to see if is a valid math expression

* fix(content): change in input validation to use react query instead of redux

* fix(content): change in types to avoid ci errors

* fix(content): remove unnecessary code after changing to react query

* fix(content): change numeric input validation path to new url and loader added

* feat: returning data in camelcase, improve UI in validation

* feat: tests added to problem editor

---------

Co-authored-by: Kyle McCormick <kyle@kylemccormick.me>
2025-12-19 10:38:19 -08:00
Areeb Sajjad
8b9f156149 fix: keyboard accessibility for time picker (#2613) 2025-12-17 16:56:54 -08:00
María Fernanda Magallanes
9c70fd9216 fix: only show library actions available for the user (#2712)
* fix: only show the options available for the user

* test: fix and add tests

* fix: improve following the best practices

* fix: apply the changes for collections and containers
2025-12-17 16:49:54 -08:00
Max Sokolski
4df44ab6cf fix: coerce multiple choice text elements to String (#2752) 2025-12-17 16:22:31 -08:00
renovate[bot]
0405156f91 chore(deps): update dependency @reduxjs/toolkit to v2.11.2 (#2755)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-17 23:55:12 +00:00
renovate[bot]
1e2e711eaf chore(deps): update dependency fast-xml-parser to v5.3.3 (#2754)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-17 15:42:14 -08:00
Navin Karkera
3eeca244d7 feat: add temporary message alert in sections settings tab in libraries (#2734)
- add temporary message alert in sections settings tab in libraries 
- increase sidebar width to remove `More` option and display all tabs
together
2025-12-17 14:21:13 -05:00
Navin Karkera
ae67be83a0 feat: new course outline header [FC-0114] (#2735)
Adds new header and subheader to course outline. Converts existing js code to ts.
2025-12-17 13:13:19 -05:00
Navin Karkera
6f37118960 refactor: update placeholder block and import details page (#2761)
* Updates placeholder block color and icon.
* Moves `View Imported Content` & `Retry import` buttons in import details page inside alert at the top.
* Updates page title to include Import status in import details page.
2025-12-17 11:43:12 -05:00
Chris Chávez
41a326f7b4 feat: New library sync icon [FC-0114] (#2739)
Updates the library sync icon with new states: error, broken, ready to sync and with overrides
2025-12-16 14:54:28 -05:00
dependabot[bot]
b7dd6706c2 chore(deps): bump actions/upload-artifact from 5 to 6 (#2756)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-15 17:59:54 +00:00
dependabot[bot]
64ab7ea4fe chore(deps): bump actions/download-artifact from 6 to 7 (#2757)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-15 09:42:37 -08:00
edX requirements bot
89d2393d6e chore: update browserslist DB (#2753)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-12-15 00:24:21 +00:00
Santhosh Kumar
42acb53201 feat!: remove "Create Zendesk Tickets for suspicious attempts" setting from Proctored Exam Settings (#2517)
BREAKING CHANGE: This PR removes the deprecated “Create Zendesk Tickets for suspicious attempts”
setting from the Proctored Exam Settings modal in the frontend-app-authoring
MFE. This option was previously used with PSI and Zendesk to generate support
tickets for suspicious exam attempts. Since both systems are retired, the
setting no longer serves a purpose and has been fully removed.

Part of: https://github.com/openedx/edx-platform/issues/36329
2025-12-11 17:05:05 -05:00
David Ormsbee
225c82d037 fix: support "in progress" status for lib upload
When uploading a library archive file during the creation of a new
library, the code prior to this commit did not properly handle the "In
Progress" state, which is when the celery task doing the archive
processing is actively running. Note that this is distinct from the
"Pending" state, which is when the task is waiting in the queue to be
run (which in practice should almost never happen unless there is an
operational issue).

Since celery tasks run in-process during local development, the task
was always finished by the time that the browser made a call to check
on the status. The problem only happened on slower sandboxes, where
processing truly runs asynchronously and might take a few seconds.
Because this case wasn't handled, the frontend would never poll for
updates either, so the upload was basically lost as far as the user
was concerned.
2025-12-11 12:58:06 -05:00
Muhammad Arslan
a596bf5d38 fix: bugs with some static asset paths in TinyMCE editors (#2702)
* fix: only convert assets static file path

* fix: direct static file is fixed

* fix: setting newContent now load the content in html as well
2025-12-11 09:19:40 -08:00
Kyle McCormick
67a5694ca3 fix: Generalize a couple remaining Proctortrack references (#2746)
Just a few leftovers from: https://github.com/openedx/frontend-app-authoring/pull/2645

Full context: https://github.com/openedx/edx-platform/issues/36329
2025-12-11 00:07:29 -05:00
dependabot[bot]
833a838348 chore(deps): bump node-forge from 1.3.1 to 1.3.2 (#2708)
Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.3.1 to 1.3.2.
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/v1.3.1...v1.3.2)

---
updated-dependencies:
- dependency-name: node-forge
  dependency-version: 1.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-10 15:21:18 -08:00
renovate[bot]
3cf1ce2b5d chore(deps): update dependency @reduxjs/toolkit to v2 (#2369)
* fix(deps): update dependency @reduxjs/toolkit to v2

* chore: minor updates to work with RTK version 2

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Braden MacDonald <braden@opencraft.com>
2025-12-10 22:46:58 +00:00
dependabot[bot]
7eea38e623 chore(deps): bump express from 4.21.2 to 4.22.1 (#2726)
Bumps [express](https://github.com/expressjs/express) from 4.21.2 to 4.22.1.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/v4.22.1/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.21.2...v4.22.1)

---
updated-dependencies:
- dependency-name: express
  dependency-version: 4.22.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-10 14:38:49 -08:00
renovate[bot]
128de3ffc4 chore(deps): update react-router monorepo to v6.30.2 (#2742)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-10 14:03:43 -08:00
Anton Melser
6724e1a296 docs: Generify currently supported node version (#2744)
- remove some non-meaningful trailing whitespace
2025-12-10 19:37:30 +00:00
Areeb Sajjad
8fc00709b4 chore: upgrade react-datepicker (#2709) 2025-12-10 11:29:19 -08:00
renovate[bot]
f367a7641d fix(deps): update dependency @tanstack/react-query to v5.90.12 (#2741)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-08 14:41:03 -05:00
edX requirements bot
49d809b809 chore: update browserslist DB (#2740)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-12-08 00:24:10 +00:00
Chris Chávez
dad736f9d1 refactor: Migration of course details to React query (#2724)
- Migrates the `courseDetails` part from the Redux Store to React Query.
- Creates a new `CourseAuthoringContext` 
- Update the pages in `<CourseAuthoringRoutes>` to use the newly created context.
- Migrates some files to Typescript
- Migrates some tests to use `src/testUtils.tsx`
2025-12-06 00:14:32 +00:00
Chris Chávez
50f4f70671 feat: Import Course Details Page [FC-0112] (#2664)
Implements all the states for the Import Course Details
2025-12-05 12:03:55 -05:00
Rodrigo Mendez
0796e897ae feat: Implement querying openedx-authz for publish permissions (#2685) 2025-12-04 14:40:32 -05:00
Chris Chávez
b76b003e01 refactor: Migrate Help Urls from Redux store to React Query (#2714) 2025-12-02 22:00:06 +00:00
renovate[bot]
e95758cc55 chore(deps): update dependency @types/lodash to v4.17.21 (#2716)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-01 18:07:35 -05:00
renovate[bot]
c7ab2b2837 chore(deps): update dependency @types/react to v18.3.27 (#2717)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-01 18:07:02 -05:00
edX requirements bot
dfe87f983b chore: update browserslist DB (#2715)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-12-01 00:25:55 +00:00
Muhammad Anas
f9e09f0601 fix: replace hardcoded edX with platformName in basicBannerTitle message (#2711) 2025-11-28 13:26:00 -05:00
Navin Karkera
0c1554b337 feat: placeholder blocks for failed import blocks (#2703)
Adds placeholder blocks in home page and respective collections tab in library for failed blocks during import from course.
2025-11-27 12:42:21 -05:00
Daniel Wong
294fe42942 feat: add support for origin server and user info (#2663)
* feat: add support for origin server and user info

* test: add coverage for restore archive summary

* test: increase coverage for restore archive summary

* fix: address comments
2025-11-27 10:04:15 -05:00
Chris Chávez
95ec41d2e7 feat: dock buttons to the bottom in import course stepper (#2694) 2025-11-26 18:18:41 -05:00
renovate[bot]
e620d70793 chore(deps): update dependency @openedx/paragon to v23.18.1 (#2701)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-26 18:15:14 -05:00
Rahat Ali
fa562a691b refactor: Replace ProctorTrack references with Generic Checks (#2645)
This pull request removes frontend-level handling of the ProctorTrack
proctoring provider from the frontend-app-authoring application.

As part of the broader ProctorTrack deprecation effort
(openedx/edx-platform#36329), the backend now provides generic proctoring
configuration rules instead of vendor-specific conditions. The frontend has
been updated to rely on these generic rules while still performing client-side
validation.

By removing the ProctorTrack-specific logic and using the backend’s generic
configuration model, this change keeps frontend-app-authoring aligned with
current backend behavior and avoids relying on deprecated vendor-specific
handling.

Co-authored-by: Taimoor  Ahmed <taimoor.ahmed@A006-01711.local>
2025-11-26 12:26:30 -05:00
Kyle McCormick
70c19a3ffb fix: "Back up" is two words when used as a verb (#2696)
There is a new menu item "Backup to local archive". Backup is the correct
spelling when using it as a noun or adjective, but the menu item uses as a
verb, so it should be two words, back up, i.e. "Back up to local archive"
2025-11-26 17:15:51 +00:00
Navin Karkera
ef36156d55 fix: consider children blocks of unsupported blocks while analyzing course import (#2684)
The analysis step before importing a course considers the parent block while counting unsupported blocks but does not include children in the unsupported count.

We fetch usage_keys of all unsupported blocks and fetch the children blocks that contain these usage_keys in their breadcrumb field i.e., they are part of the unsupported blocks.
2025-11-25 16:24:01 -05:00
dependabot[bot]
735159311d chore(deps): bump actions/checkout from 5 to 6 (#2692)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 16:02:45 -05:00
edX requirements bot
4fd52b9a4d chore: update browserslist DB (#2691)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-11-24 00:23:39 +00:00
Braden MacDonald
4a81ddbe74 refactor: convert <UnitButton> and <UnitIcon> to TSX (#2649) 2025-11-20 14:29:00 -05:00
Navin Karkera
2215fc53cc fix: don't revert to advanced editor if block contains copied_from fields (#2661) 2025-11-19 15:43:52 -05:00
renovate[bot]
23ab74da14 chore(deps): update dependency formik to v2.4.9 (#2655)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-18 18:19:25 -05:00
dependabot[bot]
1d385c6b4d chore(deps): bump js-yaml (#2659)
Bumps [js-yaml](https://github.com/nodeca/js-yaml).

Updates `js-yaml` from 3.14.1 to 3.14.2
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.14.1...3.14.2)

Updates `js-yaml` from 4.1.0 to 4.1.1
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.14.1...3.14.2)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 3.14.2
  dependency-type: indirect
- dependency-name: js-yaml
  dependency-version: 4.1.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-18 13:45:45 -05:00
renovate[bot]
acbd1de548 chore(deps): update dependency react-datepicker to v8 (#2572)
* fix(deps): update dependency react-datepicker to v8

* chore(deps): update code to work with react-datepicker v8

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Braden MacDonald <braden@opencraft.com>
2025-11-18 13:10:38 -05:00
Rômulo Penido
650bb62fa7 fix: migrate library alert text (#2651)
This PR updates the alert texts on the Migrate Libraries Stepper
2025-11-18 12:09:03 -05:00
Navin Karkera
e2f1aedf9a feat: import analysis step (#2657)
Shows course analysis information in review import details step in course import stepper page. Also handles alerts based on the import status, like, reimport or unsupported number of blocks.
2025-11-18 11:41:27 -05:00
Kyle McCormick
5fadccabe2 fix: Rename builtin discussion providers, "edX" -> "Open edX" (#2660) 2025-11-18 14:55:33 +00:00
renovate[bot]
daed664404 chore(deps): update dependency fast-xml-parser to v5.3.2 (#2594)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-17 18:07:45 +00:00
Asad Ali
495a682926 fix: do not reload multiple tabs on block save (#2600) 2025-11-17 12:54:07 -05:00
renovate[bot]
6f41cd76da chore(deps): update codemirror (#2535)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-17 17:07:01 +00:00
renovate[bot]
64489e1b4d chore(deps): update dependency @openedx/paragon to v23.18.0 (#2643)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-17 17:06:10 +00:00
renovate[bot]
91c813b214 fix(deps): update dependency @tanstack/react-query to v5.90.10 (#2654)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-17 17:05:46 +00:00
Chris Chávez
2e7a29465f refactor: Update title in ImportStepperModal (#2658)
Updates the title of one card from "Import Details" to "Analysis Details"
2025-11-17 16:51:44 +00:00
edX requirements bot
0f58329cb4 chore: update browserslist DB (#2653)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-11-17 00:22:55 +00:00
Chris Chávez
54cfbeb756 feat: import course in library stepper [FC-0112] (#2567)
- Implemented the course import stepper described in https://github.com/openedx/frontend-app-authoring/issues/2524
- Adds the new `ENABLE_COURSE_IMPORT_IN_LIBRARY` flag
2025-11-14 13:07:00 -05:00
Muhammad Anas
7cf01de84c fix: grading settings save button stuck in pending state (#2614) 2025-11-14 08:54:57 -05:00
Navin Karkera
a1abd43a11 refactor: rename team access navbar and sidebar (#2644) 2025-11-13 20:27:06 -05:00
Muhammad Anas
8f06263e27 fix: unit button active state (#2617) 2025-11-13 12:08:18 -05:00
Braden MacDonald
e10ab270dd chore: don't name unused errors in catch expressions (#2591) 2025-11-12 18:11:22 -05:00
Braden MacDonald
a5d65abea2 chore: fix no-base-to-string (#2597) 2025-11-12 13:34:00 -05:00
Braden MacDonald
5ec00236cb chore: fix unnecessary 'undefined' types (#2589) 2025-11-12 13:26:01 -05:00
Devasia Joseph
2530b01b82 fix: restrict single select questions to one correct answer (#2618) 2025-11-12 17:43:42 +05:00
renovate[bot]
13c51ce5a8 chore(deps): update dependency @tanstack/react-query to v5.90.7 (#2611)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-10 10:49:02 -05:00
edX requirements bot
b2cfafc00e chore: update browserslist DB (#2610)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-11-10 00:22:49 +00:00
Rômulo Penido
6d619b9c40 feat: add course import page [FC-0112] (#2580)
Adds the Library Import Home, which lists course migrations to the library
2025-11-07 16:32:11 -05:00
Muhammad Arslan
6afe6095a5 fix: self-closing script tag fixed for TinyMceEditor (#2510)
(not really valid HTML but preserves backwards compatibility)
2025-11-06 09:38:04 -08:00
Muhammad Arslan
1b357cb2b6 fix: broken Course Overview editor on Schedule & Details page (#2599) 2025-11-05 15:15:31 -08:00
Chris Chávez
2de987b254 style: Update some texts in legacy libraries migration flow (#2601) 2025-11-05 18:13:32 -05:00
renovate[bot]
4299bf16b4 chore(deps): update dependency @openedx/paragon to v23.16.0 (#2583)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-05 15:07:54 -08:00
Navin Karkera
5cda284cdb fix: pass readOnly flag to Header in library authoring page (#2598) 2025-11-04 17:56:37 -05:00
Navin Karkera
436ac3155d feat: nav dropdowns in library authoring view (#2556)
Updates navbar in library authoring page to include `Team Access` and `Import` menu options. Clicking on `Team Access` button opens Team management modal.

As per this new PR: https://github.com/openedx/frontend-app-authoring/pull/2570, if admin console url is set, it should be used instead of team access modal. So updated this PR accordingly.
2025-11-03 17:06:50 -05:00
renovate[bot]
86a7e06a3c chore(deps): update dependency @tanstack/react-query to v5.90.6 (#2595)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-03 09:31:38 -08:00
Navin Karkera
bd82c1d33d fix: publish status of container on adding new children (#2587)
Updates publish status of container when adding new child components to a unit or other containers.
2025-11-03 10:01:30 -05:00
Navin Karkera
75ae9d549c feat: handle duplicate children in container pages [FC-0112] (#2584)
If we have duplicate container or component in parent page in library, clicking on one of them selects both and removing any one from the parent blocks removes all instances.
This PR handles duplicates by including index/order_number of each child component in the url and using it to exclude a single instance and update parent structure.
2025-11-03 09:59:37 -05:00
edX requirements bot
cec074e6d4 chore: update browserslist DB (#2593)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-11-03 00:23:01 +00:00
Braden MacDonald
36c9eba66d refactor: remove remaining injectIntl(), ban it using eslint (#2585)
This finished the removal of `injectIntl` from this codebase, and configures a new eslint rule to ban it completely.
2025-10-30 20:10:52 -05:00
Navin Karkera
2dc087f87a feat: differentiate between renamed and data edit in sync preview diff [FC-0112] (#2577)
Use `downstream_customized` field from upstream link to determine whether the text component was locally renamed or content updated or both and display correct notes in preview diff.
Also update libraries v2 alert wording as per https://github.com/openedx/frontend-app-authoring/issues/2169#issuecomment-3434735901
2025-10-29 17:24:04 -05:00
Javier Ontiveros
9b77a40284 feat: add restore from file UI for libraries v2 (#2558) 2025-10-29 21:37:35 +00:00
renovate[bot]
871d98828c chore(deps): update dependency @openedx/paragon to v23.15.1 (#2569)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-29 09:31:41 -07:00
renovate[bot]
f116740184 chore(deps): update github artifact actions (#2571)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-27 10:49:02 -07:00
renovate[bot]
cd967a9878 chore(deps): update dependency @edx/frontend-platform to v8.5.2 (#2568)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-27 10:47:21 -07:00
Farhaan Bukhsh
d8805bf2b4 chore: Updates frontend-component-header to include new slots (#2576)
Signed-off-by: Farhaan Bukhsh <farhaan@opencraft.com>
2025-10-27 16:07:51 +00:00
Diana Olarte
0972b7e62d feat: [FC-0099] redirect to admin console MFE (#2570)
* feat: redirect to admin console MFE

This PR redirects to admin console MFE if the URL is configured, to leverage the new experience of team management this is part of the AuthZ project https://github.com/openedx/openedx-authz/tree/main/docs/decisions

* refactor: split the logic into 2 variables for readability
2025-10-27 15:59:25 +00:00
Kshitij Sobti
15a728d0e7 feat: Add slots for video and file upload components and alerts (#1523)
This change add plugin slots for the file and video upload components, and the alerts components on those pages.
2025-10-24 14:39:50 -07:00
Braden MacDonald
157e2464aa test: fix test code improperly using/missing 'await' (#2560) 2025-10-24 21:31:51 +00:00
Braden MacDonald
c54c21e2b4 test: fix warnings when StrictDict values are checked with propTypes (#2565) 2025-10-24 14:16:07 -07:00
Muhammad Anas
dc05ccfd16 feat: add never_but_include_grade visibility option (#2489)
This PR introduces a new visibility option for assignment scores:

“Never show individual assessment results, but show overall assessment results after the due date.”

With this option, learners cannot see question-level correctness or scores at any time. However, once the due date has passed, they can view their overall score in the total grades section on the Progress page.
2025-10-24 15:08:32 -03:00
Chris Chávez
106f22b3c2 chore: Enable legacy libraries migration by default (#2561) 2025-10-22 18:20:55 -05:00
Chris Chávez
76d8b2e03a feat: Add error messages for partial migration [FC-0107] (#2555)
Adds the error messages for partial migrations
2025-10-22 17:07:24 -05:00
Kyle McCormick
5ce61fa5e5 feat: Add ability to create Legacy Libraries (#2551)
This adds a CreateLegacyLibrary component. It functions the same as
CreateLibrary, but it calls the V1 (legacy) creation REST API rather the V2
(new/beta) REST API.

This reinstates, in the MFE, something that was possible using the legacy
frontend until it was prematurely removed by
https://github.com/openedx/edx-platform/pull/37454. 

We plan to re-remove this ability between Ulmo and Verawood as part of:
https://github.com/openedx/edx-platform/issues/32457.
So, we have intentionally avoided factoring out common logic between
CreateLibrary and CreateLegacyLibrary, ensuring that the latter
remains easy to remove and clean up.
2025-10-22 21:33:59 +00:00
Chris Chávez
46fa17ea83 fix: UI fixes in legacy library migrator
- Keep state of all migration steps on nevigation
- Reword alert in confirm dialog
- Add scroll to help sidebar in migration
- Keep the same migration filter
2025-10-22 21:24:52 +00:00
Chris Chávez
9f1604110b feat: Deleted/Added level diff in sync modal [FC-0097] (#2549)
- Adds the Deleted and the Added level diff in sync container modal.
- Fix the icons in the sync container modal
2025-10-22 20:53:12 +00:00
Muhammad Anas
82a3c2815b feat: enable markdown to OLX conversion (#2518) 2025-10-21 16:58:20 -07:00
renovate[bot]
191be55b2e chore(deps): update dependency @tanstack/react-query to v5.90.5 (#2545)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-20 17:55:40 -07:00
renovate[bot]
8f7e48421f chore(deps): update actions/setup-node action to v6 (#2546)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-20 17:32:11 -07:00
dependabot[bot]
b6de9a8883 chore(deps): bump actions/setup-node from 5 to 6 (#2547)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 5 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-20 17:29:38 -07:00
Javier Ontiveros
7bfc73073b [feature] add backup view for libraries v2 (#2532)
* feat: add backup view for libraries v2

* chore: updated paths and cleanup

* chore: cleanup text

* chore: added test

* chore: fix contracts after rebase

* chore: more tests to improve coverage

* chore: more test for coverage

* chore: more test for coverage

* chore: fixed lint issues

* chore: update naming for a more semantic one

* chore: changed fireEvent to userEvent

* chore: improved queryKeys

* chore: lint cleanup

* chore: changed tests and time to 1min

* chore: even more tests

* chore: split hook for library menu items

* chore: fixed typo on refactor

* chore: improved test to use available mocks

* chore: change from jest.mocks to spyon

* chore: update test based on commets

* chore: update test to get URL from a better place

* chore: added extra getters for new endpoints

* chore: update test to prevent issues with useContentLibrary

* chore: added comments for clarity

* chore: lint fix

* chore: updated url handle to use full URL

* chore: linting fixes
2025-10-20 16:51:05 -06:00
renovate[bot]
98009b3e6a chore(deps): update dependency @edx/frontend-component-footer to v14.9.3 2025-10-20 16:34:05 -03:00
Navin Karkera
e80930e06f fix: add components button in item bank children page (#2491)
`Add components` button in item bank children page was not working.
2025-10-20 12:09:58 -05:00
edX requirements bot
66dad5ff32 chore: update browserslist DB (#2544)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-10-20 00:22:22 +00:00
bydawen
e4ea69266f fix: pointer-events issue on toast container (#2139) 2025-10-17 14:26:03 -07:00
Rômulo Penido
8b6a350808 feat: add copy container menu (#2538)
Adds copy support for Library Containers and updates the useClipboard hook to provide info on copied containers.
2025-10-17 14:11:18 -05:00
renovate[bot]
a56faf8ca7 fix(deps): update dependency @tinymce/tinymce-react to v6 (#2536)
* fix(deps): update dependency @tinymce/tinymce-react to v6

* refactor: validating typing of tinymce-react usage (no runtime changes)

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Braden MacDonald <braden@opencraft.com>
2025-10-16 22:07:27 +00:00
renovate[bot]
77215eeb5e chore(deps): update dependency @openedx/paragon to v23.14.9 (#2533)
* chore(deps): update dependency @openedx/paragon to v23.14.9

* test: update tests because of paragon role=presentation modal changes

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Braden MacDonald <braden@opencraft.com>
2025-10-16 16:53:39 +00:00
Chris Chávez
311bef67ed feat: Shows an alert in container sync if the only change is a local override to a text component [FC-0097] (#2516)
- Implements the alert described in https://github.com/openedx/frontend-app-authoring/issues/2438#issuecomment-3358670967
2025-10-15 19:17:56 -05:00
Chris Chávez
195249ef26 feat: Legacy libraries migration help sidebar [FC-0097] (#2503)
- Implements the Legacy Libraries Migration Help Sidebar
- Shows the sidebar in the studio home
- Shows the sidebar in the Legacy Libraries Migration Page
2025-10-15 20:35:08 +00:00
Ihor Romaniuk
4a26a86c90 fix: answer range format validation in numerical input problems (#2426) 2025-10-15 11:33:31 -07:00
vladislavkeblysh
411d4f053c fix: fixed delete for additional video url fields in video editor (#2470) 2025-10-15 09:47:03 -07:00
Chris Chávez
9c0b545b2f feat: Connect bulk migration backend with frontend (#2493)
- Connects the `Confirm` button with the bulk migrate backend
- Updates the library page to get the migration task status and refresh the component on success.
2025-10-14 00:04:36 +00:00
Ahtesham Quraish
cd36407457 fix: [Library browse] Unintended scroll upon unit selection #2452 (#2472) 2025-10-13 09:22:22 -05:00
Chris Chávez
46d2465064 fix: Multiple UI/UX improvements (#2529)
This includes multiple improvements described in https://github.com/openedx/frontend-app-authoring/issues/2528
2025-10-13 09:21:00 -05:00
edX requirements bot
6c829b9421 chore: update browserslist DB (#2534)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-10-13 00:22:24 +00:00
Kyle McCormick
1d6fdc39fd feat: frontend-component-header to 8.0.0, to rm Maintenance link (#2521)
BREAKING CHANGE: Removes Maintenance link in header, part of
https://github.com/openedx/edx-platform/issues/36263

Full diff:
https://github.com/openedx/frontend-component-header/compare/v6.2.0...v8.0.0
2025-10-10 12:38:02 -04:00
Ahtesham Quraish
04e9a253ba fix: library card icons are not vertically aligned #2473 (#2474) 2025-10-10 09:01:13 -07:00
Ahtesham Quraish
8470d7cd4d fix: Rename field should use full available width #2337 (#2436) 2025-10-10 09:00:40 -07:00
renovate[bot]
b774084a10 chore(deps): update dependency @openedx/paragon to v23.14.5 (#2530)
* chore(deps): update dependency @openedx/paragon to v23.14.5

* fix: correct type of ContainerPropsType

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Braden MacDonald <braden@opencraft.com>
2025-10-09 17:14:33 +00:00
MuPp3t33r
aadccc748c fix: course assets state persistence bug (#2401) 2025-10-08 11:36:26 -07:00
Navin Karkera
c4a439df47 fix: show before and after title in diff preview (#2509)
Fix display of Before and After display name in section/subsection sync preview modal.
2025-10-07 14:52:22 -05:00
renovate[bot]
8fe5fb6a20 chore(deps): update dependency universal-cookie to v8 (#2512)
* fix(deps): update dependency universal-cookie to v8

* refactor: validate typing of universal-cookie usages

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Braden MacDonald <braden@opencraft.com>
2025-10-06 23:08:46 +00:00
renovate[bot]
0315c05e11 chore(deps): update dependency fast-xml-parser to v5 (#2515)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-06 22:41:17 +00:00
renovate[bot]
a5d51ce4f4 chore(deps): update dependency @types/react to v18.3.26 (#2513)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-06 15:25:18 -07:00
renovate[bot]
3a6378e569 chore(deps): update dependency @testing-library/jest-dom to v6.9.1 (#2508)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-06 14:40:55 -07:00
renovate[bot]
e37f2e0071 chore(deps): update dependency @types/react to v18.3.25 (#2507)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-06 14:40:18 -07:00
edX requirements bot
835de77385 chore: update browserslist DB (#2506)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-10-06 00:21:27 +00:00
renovate[bot]
7f23e9b585 chore(deps): update dependency @openedx/paragon to v23.14.4 (#2504)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-04 00:30:06 +00:00
renovate[bot]
32ed2f183b chore(deps): update codemirror (#2487)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-04 00:29:54 +00:00
renovate[bot]
292068af6e chore(deps): update dependency @tanstack/react-query to v5.90.2 (#2488)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-03 17:17:05 -07:00
Chris Chávez
a975f3b716 feat: New modal to sync changes for standalone text components [FC-0097] (#2449)
Adds a new sync modal when a Text component has local changes.
2025-09-30 09:45:13 -05:00
Chris Chávez
1c7ad2f725 feat: Migrate Legacy Libraries Flow [FC-0097] (#2425)
- Creates all steps of the flow described in https://github.com/openedx/frontend-app-authoring/issues/2201
2025-09-29 18:02:15 -05:00
renovate[bot]
7ba3db0187 chore(deps): update dependency @openedx/paragon to v23.14.3 (#2485)
* chore(deps): update dependency @openedx/paragon to v23.14.3

* fix: ref was invalid and causing console error

"Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?"

(Paragon does not support refs for IconButtonWithTooltip, although it could be added at any time.)

* fix: react query console error in tags drawer

"No queryFn was passed as an option, and no default queryFn was found. The queryFn parameter is only optional when using a default queryFn."

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Braden MacDonald <braden@opencraft.com>
2025-09-29 21:07:49 +00:00
edX requirements bot
fdf98a1400 chore: update browserslist DB (#2486)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-09-29 00:21:05 +00:00
Chris Chávez
56d3eede64 feat: Adding loading and done states to the publish library button [FC-0097] (#2237)
Adds loading and done states to the publish library button.
2025-09-26 15:15:23 +00:00
oleksandr.buhaienko
c5de944d72 test: Remove support for Node 20 2025-09-26 10:29:24 -03:00
Rômulo Penido
523dd1f389 feat: add library v2 alert (#2413)
Adds an Alert to the Legacy Library Page to notify the user of the process of deprecating Legacy Libraries and a Button to open the Migrate Library interface.
2025-09-25 16:01:57 -05:00
Navin Karkera
cffc4d77c9 feat: migration filter and search bar in legacy libraries tab [FC-0097] (#2421)
Adds search bar and migration filter in legacy libraries tab
2025-09-25 17:00:26 +00:00
Navin Karkera
25160347b3 feat: container library-course sync diff prevew [FC-0097] (#2464)
Container sync preview implemented
2025-09-25 11:13:58 -05:00
Navin Karkera
d63680083d feat: show migration status in libraries list [FC-0097] (#2417)
Adds migration status to library cards in legacy libraries tab in studio home.
Also converts javascript files to typescript and replaces redux with react query for related api calls.
2025-09-25 10:49:13 -05:00
bydawen
39e5f89b45 build: Upgrade to Node 24 (#2459) 2025-09-22 09:49:04 -07:00
edX requirements bot
7e81b52583 chore: update browserslist DB (#2469)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-09-22 00:22:14 +00:00
Rômulo Penido
1efa94d410 fix: update delete and remove modals design [FC-0097] (#2453)
Changes the Remove/Delete Component/Container dialogs according to the design. It also standardized the messages from Components and Containers.
2025-09-18 16:27:35 -05:00
bydawen
d98a34ac3f test: Add Node 24 to CI matrix (#2443) 2025-09-18 10:09:51 -07:00
Akanshu Aich
8b530481de fix: remove unused ENABLE_HOME_PAGE_COURSE_API_V2 config reference (#2461) 2025-09-18 09:49:03 -07:00
Muhammad Faraz Maqsood
9f6a882e61 fix: course optimizer issues (#2450)
- don't show `Scan results` heading until there are some results to show.
- change spinner from paragon with spinner icon which looks better than spinner itself.
- disable `update all` button when single update prev Link is in progress.

Co-authored-by: Muhammad Faraz  Maqsood <faraz.maqsood@A006-01130.local>
2025-09-18 10:44:18 +05:00
renovate[bot]
b95b3a60ad chore(deps): update dependency @tanstack/react-query to v5 (#2404)
* fix(deps): update dependency @tanstack/react-query to v5

* chore: update for compatibility with React Query v5

* chore: update for compatibility with React Query v5

* test: update tests

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Braden MacDonald <braden@opencraft.com>
2025-09-17 16:10:08 -07:00
Navin Karkera
61c87fe6a6 feat: allow editing imported unit blocks (#2405)
Allows authors to edit imported unit display name in outline.
2025-09-17 12:27:04 -05:00
renovate[bot]
c21b664a8b chore(deps): update codemirror to v6.4.10 (#2432)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-16 10:50:08 -07:00
Chris Chávez
71376fa22b feat: ENABLE_LEGACY_LIBRARY_MIGRATOR flag added (#2440)
- Adds the `ENABLE_LEGACY_LIBRARY_MIGRATOR` flag. **Reason:** The migrator frontend is finishing before the backend; this flag is mainly to hide it until it is fully connected and working with the backend.
- Puts the migration warning under the new flag.
2025-09-12 11:20:31 -05:00
Chris Chávez
23b4f4731e fix: Use the correct branch of openedx/.github repo for add-cc-to-board (#2441) 2025-09-11 12:33:10 -07:00
Chris Chávez
ab645ad86b feat: add-to-cc-board Github action created. (#2302)
- This is a label trigger to add an Issue or PR to the front-end [Core Contributor project board](https://github.com/orgs/openedx/projects/80).
- This action uses the `Core Contributor assignee` label as a trigger.
- This action reuses https://github.com/openedx/.github/pull/169
- When you add the label to an issue or PR, it is automatically added to the board https://github.com/orgs/openedx/projects/80
2025-09-10 17:10:38 -05:00
Navin Karkera
720b591add feat: display only one card action overflow menu (#2427)
Instead of stopping whole click event propagation from actions to card element, specifically stop click event if the source target is actions menu.
2025-09-08 16:47:17 -05:00
renovate[bot]
87239ab723 chore(deps): update dependency @types/react to v18.3.24 (#2431)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-08 09:41:52 -07:00
Asad Ali
0117c1eae3 fix: allow thumbnail upload on Videos page if no thumbnail (#2388)
* fix: allow thumbnail upload if no thumbnail

* fix: improve thumbnail upload impl

* test: fix tests

* test: fix tests

* fix: do not show thumbnail upload if not allowed

* test: fix coverage

* test: add thumbnail test

* fix: display thumbnail overlay when video status is success
2025-09-08 09:40:32 -07:00
Ahtesham Quraish
0f7c8de882 fix: files page web url missing #2409 (#2420)
Co-authored-by: Ahtesham Quraish <ahtesham.quraish@A006-01455.local>
2025-09-08 09:33:19 -07:00
dependabot[bot]
387c45a5b2 chore(deps): bump actions/setup-node from 4 to 5 (#2433)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 5.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-08 09:00:29 -07:00
edX requirements bot
6377fbd896 chore: update browserslist DB (#2430)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-09-08 00:22:14 +00:00
Chris Chávez
67fab054ab feat: Secondary publish workflow for components [FC-0097] (#2399)
- Adds the new publish button and the new confirm publish box for components.
- Deletes the old confirm publish modal for components
- Adds the publish button next to the open button for containers 
- Update changes to grand-parent and grand-child items.
2025-09-05 17:12:40 +00:00
renovate[bot]
a7860b8392 chore(deps): update dependency @edx/frontend-component-header to v6.6.1 (#2407)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-04 02:20:41 +00:00
renovate[bot]
3082eca91c chore(deps): update dependency @edx/frontend-component-footer to v14.9.1 (#2415)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-03 19:07:46 -07:00
Rômulo Penido
2fb04d670f feat: add legacy library alert (#2412)
Adds an Alert to the Legacy Library Page to notify the user of the process of deprecating Legacy Libraries and a Button to open the Migrate Library interface.
2025-09-02 14:23:49 -05:00
Samuel Allan
f79b65c273 fix: update frontend-build to fix install issues (#2387)
Earlier versions of @openedx/frontend-build used on older version of
'sharp', which caused intermittent installation issues. The version of
'sharp' was updated in @openedx/frontend-build to fix these issues, so
the frontend-build version can be updated here, to fix the issues in
this project too. See
https://github.com/openedx/frontend-build/issues/664 and
https://github.com/openedx/frontend-build/pull/665 for more information.

The frontend-build dependency was updated by:

```
npm install --package-lock-only @openedx/frontend-build
```

Private-ref: https://tasks.opencraft.com/browse/BB-9953
2025-09-02 09:48:30 -07:00
Pandi Ganesh
472d77823f feat: Enhance Course Optimizer Page with Previous Run Links and Improved UI (#2356)
* feat: enhance course optimizer page design in studio

* feat: enhance course optimizer with prev run links update

* fix: increase container size and resolve style issues

* fix: enhance code structure and i18n support
2025-09-02 17:01:28 +05:00
edX requirements bot
09f4304daa chore: update browserslist DB (#2414)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-09-01 00:23:43 +00:00
Rômulo Penido
950bfee7c1 feat: add unlink upstream menu [FC-0097] (#2393)
Adds the Unlink feature to the Course Outline for Sections, Subsections and Units.
2025-08-28 11:44:15 -05:00
Pradeep
0f2dd4a88f fix: ensure hyperlink renders correctly based on videoSource presence (#2400)
* fix: ensure hyperlink renders correctly based on videoSource presence

* refactor: remove unnecessary blank lines in VideoPreviewWidget tests
2025-08-28 14:44:17 +05:00
Chris Chávez
6646c8ed0f style: Fixing nits about sync units [FC-0097] (#2319)
* Stay visible the sync icon in the course outline
* Update the message in the sync unit/subsection/section modal
* Add a tooltip to the edit and sync button.
2025-08-27 19:29:24 -05:00
Vivek Ambaliya
9a9806ccad feat: add new help section in course team page 2025-08-27 14:08:16 +05:00
Muhammad Faraz Maqsood
86e9c6b1fa fix: tinyMCE images previews in image selection modal 2025-08-26 11:28:27 +05:00
renovate[bot]
2a787953ef chore(deps): update dependency @testing-library/jest-dom to v6.8.0 (#2403)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-25 12:29:24 -07:00
Braden MacDonald
c90195e0fd refactor: move 'isMarkdownEditorEnabledForContext' into EditorContext (#2398)
This just moves one single state variable, `isMarkdownEditorEnabledForCourse` out of the Redux state and into the `EditorContext`.
2025-08-25 12:31:39 -05:00
edX requirements bot
dfd3b93f0a chore: update browserslist DB (#2402)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-08-25 00:22:18 +00:00
renovate[bot]
ae449b914b chore(deps): update dependency @openedx/paragon to v23.14.2 (#2375)
* fix(deps): update dependency @openedx/paragon to v23.14.2

* chore: fix invalid 'size' passed to <Spinner>

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Braden MacDonald <braden@opencraft.com>
2025-08-22 16:45:18 +00:00
Kshitij Sobti
5c006af6ec fix: restore styling for header title and button on outline page (#2385)
In a previous PR #2374 some of the styling applied in addition to truncation
was lost. This restores that.
2025-08-22 09:14:48 -07:00
Braden MacDonald
641fc589a4 Add TypeScript types to the redux state (#2394)
Adds some TypeScript types to the global redux state that's in `src/store.ts`. I've only added types for a few parts of the state but already it's caught quite a few bugs in the code, which I've tried to fix in this PR.
2025-08-22 11:00:19 -05:00
Chris Chávez
0c88fd6da9 feat: show sync button on section/subsections [FC-0097] (#2324)
- Adds the sync button on section/subsection cards
2025-08-21 21:38:16 +00:00
Braden MacDonald
8e680dc8d4 refactor: minor typing improvements (#2395)
This makes some minor typing improvements in our test code. Specifically instead of just `{...} as XBlock` which is an unsafe cast, we can use `{...} satisfies Partial<XBlock> as XBlock` which is a safer cast that lets you omit fields but requires that the fields you do include have the correct type.
2025-08-21 12:24:18 -05:00
Jillian
2f6e510b09 Display Container Publish status and confirm before publish (#2186)
Updates the Container sidebar to display:

* A confirmation step before publishing the container.
* Text + a full hierarchy to better demonstrate what will be published when the container is published.
2025-08-20 13:22:30 -05:00
Ahtesham Quraish
87af7e8973 refactor: Replace of injectIntl with useIntl() part 8 #2288 (#2357)
Co-authored-by: Ahtesham Quraish <ahtesham.quraish@192.168.1.4>
2025-08-20 11:07:24 -07:00
Ahtesham Quraish
33c445ebc2 refactor: Replace of injectIntl with useIntl() part 6 - files-and-videos/generic/EditFileErrors (#2358)
Co-authored-by: Ahtesham Quraish <ahtesham.quraish@192.168.1.4>
2025-08-20 10:58:02 -07:00
dependabot[bot]
7825bcde75 chore(deps): bump brace-expansion (#2381)
Bumps  and [brace-expansion](https://github.com/juliangruber/brace-expansion). These dependencies needed to be updated together.

Updates `brace-expansion` from 2.0.1 to 2.0.2
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v2.0.1...v2.0.2)

Updates `brace-expansion` from 1.1.11 to 1.1.12
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v2.0.1...v2.0.2)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 2.0.2
  dependency-type: indirect
- dependency-name: brace-expansion
  dependency-version: 1.1.12
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-18 18:19:11 -07:00
Rômulo Penido
2c9f90ba5a fix: change container sync status icon [FC-0097] (#2360)
Changes the sync icon for Sections, Subsections, and Units in case the Upstream source is deleted.
2025-08-18 17:21:47 -05:00
renovate[bot]
ada52c3169 chore(deps): update dependency @testing-library/jest-dom to v6.7.0 (#2382)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-18 09:35:24 -07:00
renovate[bot]
38b0b6543b chore(deps): update actions/checkout action to v5 (#2383)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-18 09:34:54 -07:00
Muhammad Faraz Maqsood
e6b72453b3 chore: add missing problem text for localization 2025-08-18 17:12:13 +05:00
edX requirements bot
0820a1e7df chore: update browserslist DB (#2350)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-08-18 00:23:20 +00:00
Sara Burns
be82e96e6f feat: add xblockScroll event handler to iframeMessageTypes (#2363)
* fix: new message type to scroll outer window to xblock location

* fix: reset after testing

* fix: formatting

* test: add test coverage

* fix: fix test mocks

* fix: formatting

* fix: add smooth to scroll
2025-08-15 09:11:21 -04:00
renovate[bot]
b2203f0ece chore(deps): update dependency @codemirror/lang-markdown to v6.3.4 (#2367)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-15 02:31:13 +00:00
Kshitij Sobti
53e925e07a fix: Replace Truncate.Deprecated with CSS-based truncation (#2374)
The Truncate element as it exists has a bug where it can end up in an infinite loop when truncating to a very small size on mobiles. This makes the course outline view unresponsive on mobile and can lead to a crash.

This replaces the Truncate element with some CSS.
2025-08-14 19:12:07 -07:00
Chris Chávez
25830a2130 feat: Show sections/subsections/units available for sync in library sync page [FC-0097] (#2271)
- Adds Units, Subsection, and section cards in the libraries sync page.
- Rename of `mockGetEntityLinks` to `mockGetComponentEntityLinks`
- Use the top-level parent logic
- Which user roles will this change impact? "Course Author".
2025-08-14 12:59:29 -05:00
renovate[bot]
6ce7b86e83 chore(deps): update dependency @testing-library/jest-dom to v6.6.4 (#2366)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-11 14:16:14 -07:00
Victor Navarro
5bdef7cffa fix: disable special exams config if feature flag is disabled (#2325)
* fix: disable special exams config if feature flag is disabled

* test: add testcases

* fix: convert AdvancedTab to typescript
2025-08-11 13:24:38 -07:00
renovate[bot]
f0c5a513de chore(deps): update actions/download-artifact action to v5 (#2364)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-08 13:03:05 -07:00
Navin Karkera
da46fe0a48 fix: remove interactivity from section/subsection preview in sidebar (#2362)
Removes interactivity from section/subsection preview in sidebar. Also fixes an issue with unit sidebar, where users could press enter after clicking on any component and it would select it.
2025-08-08 10:45:15 -05:00
Ahtesham Quraish
7c4ef47da5 refactor: replace one injectIntl with useIntl, fix JSX return (#2354)
Co-authored-by: Ahtesham Quraish <ahtesham.quraish@192.168.1.4>
2025-08-07 13:47:43 -07:00
renovate[bot]
8003453b73 chore(deps): update dependency @edx/frontend-platform to v8.5.0 (#2355)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-07 12:52:14 -07:00
Navin Karkera
92c3a98a3d fix: show/hide add unit button based on childAddable flag of parent in unit page (#2351)
Course unit page shows Add Unit option without checking whether the parent subsection allows adding children. This fixes it.
2025-08-06 14:41:05 -05:00
dependabot[bot]
0e1550a45b chore(deps): bump js-toml from 1.0.1 to 1.0.2 (#2353)
Bumps [js-toml](https://github.com/sunnyadn/js-toml) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/sunnyadn/js-toml/releases)
- [Commits](https://github.com/sunnyadn/js-toml/compare/v1.0.1...v1.0.2)

---
updated-dependencies:
- dependency-name: js-toml
  dependency-version: 1.0.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-05 16:05:06 -07:00
renovate[bot]
15c79ceb21 chore(deps): update dependency @openedx/paragon to v23.14.1 (#2348)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-05 13:37:42 -07:00
renovate[bot]
43de4d1e32 chore(deps): update dependency @edx/frontend-component-header to v6.6.0 (#2349)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-05 13:36:10 -07:00
Braden MacDonald
591444d72d test: Clean up editor tests (#2343)
* test: improve the editorRender helper

* fix: redux state bug introduced in #2326

* test: add note for future reference about accessing the editor redux store
2025-08-05 10:41:44 -07:00
Pradeep Patro
2f9566c4f5 refactor: Problem type handling to support localization
- Updated hooks and components to utilize localized problem titles and descriptions.
- Introduced `getProblemTypes` and `getAdvanceProblems` functions for internationalization support.
- Enhanced tests to verify localized titles and descriptions for problem types.
- Added new messages for various problem types and their descriptions.
- Refactored `TypeCard`, `TypeRow`, and `SelectTypeModal` components to use localized strings.
- Improved test coverage for problem type selection and rendering.
2025-08-05 15:37:18 +05:00
Navin Karkera
915bd559e0 feat: disable drag handles for children of library imported containers in course outline [FC-0097] (#2311)
* Hides/disables drag handles for children components of containers imported from library.
* Disables move, delete and duplicate options for children components.
* Move up and down option skips containers that cannot accept children (imported from library).
* Authors cannot drag and drop xblocks under containers imported from library.
* Improves drag-n-drop by creating a representational drag overlay.
2025-08-04 11:46:39 -05:00
Ishan Masdekar
00ce3d7856 feat: navigates subsection breadcrumb to first unit page (#2329)
- navigates the breadcrumb to the first unit under the subsection
instead of the outline page.

Closes #1924
2025-07-31 14:26:18 -07:00
Kyle McCormick
90ddc5e71c chore: Delete CODEOWNERS (#2347)
See: https://github.com/openedx/axim-engineering/issues/1511
2025-07-31 16:18:31 -04:00
renovate[bot]
9ceebbe137 chore(deps): update dependency @edx/frontend-component-header to v6.5.2 (#2334)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-29 13:19:42 -07:00
Ahtesham Quraish
8326257938 refactor: Replace connect with useSelector() and useDispatch() 1/5 2025-07-29 13:03:04 +05:00
Ahtesham Quraish
30cfd269e2 refactor: Replace of injectIntl with useIntl() part 5 #2285 2025-07-29 10:08:31 +05:00
renovate[bot]
082a1c6510 chore(deps): update dependency @edx/frontend-component-header to v6.5.1 (#2309)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-25 15:09:34 -07:00
renovate[bot]
a146307a4f chore(deps): update dependency @codemirror/view to v6.38.1 (#2303)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-25 14:10:55 -07:00
Jacobo Dominguez
556bb1e56d docs: update readme for AdditionalTranslationsComponentSlot (#2321) 2025-07-25 13:57:08 -07:00
Jorg Are
bd2e2d8655 feat: Add pt-BR to videoTranscriptLanguages (#2242) 2025-07-25 12:47:11 -04:00
dependabot[bot]
11de4022f0 chore(deps): bump on-headers and compression (#2328)
Bumps [on-headers](https://github.com/jshttp/on-headers) and [compression](https://github.com/expressjs/compression). These dependencies needed to be updated together.

Updates `on-headers` from 1.0.2 to 1.1.0
- [Release notes](https://github.com/jshttp/on-headers/releases)
- [Changelog](https://github.com/jshttp/on-headers/blob/master/HISTORY.md)
- [Commits](https://github.com/jshttp/on-headers/compare/v1.0.2...v1.1.0)

Updates `compression` from 1.8.0 to 1.8.1
- [Release notes](https://github.com/expressjs/compression/releases)
- [Changelog](https://github.com/expressjs/compression/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/compression/compare/1.8.0...v1.8.1)

---
updated-dependencies:
- dependency-name: on-headers
  dependency-version: 1.1.0
  dependency-type: indirect
- dependency-name: compression
  dependency-version: 1.8.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-24 17:06:52 -07:00
dependabot[bot]
9caa4351ba chore(deps): bump form-data from 4.0.2 to 4.0.4 (#2308)
---
updated-dependencies:
- dependency-name: form-data
  dependency-version: 4.0.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-24 16:54:00 -07:00
Muhammad Qasim Gulzar
74e671d08b fix: Course outline — issue when editing Section/Subsection/Unit name, and executing an action on the page (#2275)
When editing the title of a section, subsection or unit name, if someone created a new subsection, it would be duplicated and created twice. This change filters out the duplicate entry and eliminates the issue.
2025-07-24 12:40:48 +05:30
Navin Karkera
5b7efc65bc feat: add library reuse indicators to all components in course outline [FC-0097] (#2295)
Add library reuse indicator to units, subsections and sections in course outline.
2025-07-23 13:13:28 -05:00
Ahtesham Quraish
f9cd15eee6 fix: press Cancel it's not properly refreshing the unit and not showing the blank component was added. 2025-07-23 14:13:06 +05:00
Jacobo Dominguez
bad66caadd docs: update readme for additional course plugin slot (#2315) 2025-07-22 13:42:48 -07:00
Jacobo Dominguez
2ae594f23c refactor: replacing injectIntl with useIntl part 4 (#2301) 2025-07-22 09:49:33 -07:00
renovate[bot]
8e3ea89339 chore(deps): update dependency axios-mock-adapter to v2 (#2304)
* chore(deps): update dependency axios-mock-adapter to v2

* test: update tests for compatibility with axios-mock-adapter v2

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Braden MacDonald <braden@opencraft.com>
2025-07-21 23:27:28 +00:00
Navin Karkera
537b3292ee feat: library section subsection reuse in course (#2279)
Adds option for course author to import and use sections and subsections from library v2.
2025-07-21 15:38:47 -05:00
Ahtesham Quraish
46d5917303 refactor: Replace of injectIntl with useIntl() part 7 (#2297) 2025-07-18 14:52:57 -07:00
Jacobo Dominguez
4f3904ea4c refactor: replacing injectIntl with useIntl part 3 (#2300) 2025-07-18 14:47:18 -07:00
Ahtesham Quraish
215f7280da refactor: Replace of injectIntl with useIntl() part 6 (#2298) 2025-07-18 14:37:03 -07:00
Jacobo Dominguez
60417a76cb refactor: replacing injectIntl with useIntl part 2 (#2299) 2025-07-18 14:21:39 -07:00
Jacobo Dominguez
cbec6505f5 refactor: replacing injectIntl with useIntl part 1 (#2296) 2025-07-18 14:21:26 -07:00
Diana Villalvazo
654daa58ee fix: Change "choose library" phrasing depending on contentType (#2276)
* fix: change library dialog phrasing depending on contentType

* fix: separate i18n messages

* fix: i18n improvements
2025-07-17 16:20:24 -07:00
Braden MacDonald
bd18e874b5 Fix broken StudioHome tests (#2291)
There were a ton of problems with these tests, but the main one was the use of `waitFor` without `await`, causing all of the code inside each `waitFor` block to essentially be ignored.

Other problems fixed:
* Rendering a router inside a router was causing most of the render() calls to fail (our custom `render()` already provides a router so there's no need to provide one in the test case)
* Use of `testid` instead of queries based on what users see
* Tests could match on content in the body when trying to make assertions about the header
* Mock imported via `index.js` was causing `jest-haste-map` to print warnings about duplicate mock names (this is still happening for other mocks)
* Passing `courses: null` instead of `courses: []` was causing a broken render on two of the tests.

I also made other cleanups to follow best practices.
2025-07-17 15:45:22 -05:00
jacobo-dominguez-wgu
2db6d89fca test: upgrading user-event to v14 (#2277) 2025-07-17 09:26:16 -07:00
Ahtesham Quraish
a51ff99042 fix: Files and Uploads search text is lost when using Sort and Filter more than once 2025-07-17 10:36:34 +05:00
renovate[bot]
966767ffd4 chore(deps): update dependency react-select to v5.10.2 (#2273)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-14 14:32:29 -07:00
renovate[bot]
fc9ded432a chore(deps): update dependency @edx/frontend-component-header to v6.4.2 (#2272)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-14 14:30:29 -07:00
Muhammad Faraz Maqsood
a3e03dc12f Revert "Remove unused <EditorContainer> and URL route" (#2274) 2025-07-14 12:10:13 -04:00
Devasia Joseph
77fe2d1086 feat: Update Course Optimizer label from BETA to NEW 2025-07-11 19:03:30 +05:00
jacobo-dominguez-wgu
efd967a42b test: replacing shallow snapshots with RTL part 2 (#2267) 2025-07-10 16:49:16 -07:00
jacobo-dominguez-wgu
eaba380417 test: replacing shallow snapshots with RTL (#2266) 2025-07-10 16:47:20 -07:00
Diana Villalvazo
f3332a214f fix: remove old editorContainer (#2268) 2025-07-10 16:44:41 -07:00
jacobo-dominguez-wgu
bc11aaf5ce test: removing @edx/react-unit-test-utils library (#2263) 2025-07-08 13:27:36 -07:00
jacobo-dominguez-wgu
4ae9d3c8df test: replacing snapshot tests with RTL tests part 16 (#2252) 2025-07-08 10:08:32 -07:00
jacobo-dominguez-wgu
3673c5f561 test: replacing snapshot tests with RTL tests part 14 (#2236) 2025-07-08 09:37:07 -07:00
jacobo-dominguez-wgu
2fe24f39ac test: replacing snapshot tests with RTL tests part 13 (#2233) 2025-07-08 09:33:53 -07:00
jacobo-dominguez-wgu
c4f565bf76 test: replacing snapshot tests with RTL tests part 15 (#2248) 2025-07-07 16:44:01 -07:00
Braden MacDonald
e8e5a3c4ce docs: update PR template (#2215)
* docs: update PR template

* docs: incorporate suggestions from PR review
2025-07-07 23:04:58 +00:00
renovate[bot]
749c0022ec chore(deps): update dependency @edx/frontend-component-header to v6.4.1 (#2245)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-07 22:47:12 +00:00
Daniel Valenzuela
642be162d7 fix: open component with keyboard within unit page (#2256)
When selecting a component inside a unit with the keyboard, opening it in the sidebar by pressing enter was not working.
2025-07-07 17:34:21 -05:00
jacobo-dominguez-wgu
a969de4d90 test: replacing snapshot tests with RTL tests part 12 (#2222) 2025-07-07 15:25:27 -07:00
renovate[bot]
8d86433748 chore(deps): update dependency codemirror to v6.0.2 (#2240)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-07 22:12:46 +00:00
renovate[bot]
90f375939a chore(deps): update codemirror sub-packages (#1908)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-07 15:12:22 -07:00
renovate[bot]
a1214f7fa9 chore(deps): update react-router monorepo to v6.30.1 (#2156)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-07 14:57:24 -07:00
renovate[bot]
88821077cb chore(deps): update dependency @openedx/paragon to v23.14.0 (#2191)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-07 21:56:17 +00:00
renovate[bot]
3ebd2372d2 chore(deps): update dependency @tanstack/react-query to v4.40.1 (#2260)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-07 21:55:52 +00:00
renovate[bot]
6014da9a22 chore(deps): update dependency @types/lodash to v4.17.20 (#2259)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-07 14:42:36 -07:00
edX requirements bot
f355a17943 chore: update browserslist DB (#2258)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-07-07 00:22:40 +00:00
Daniel Valenzuela
ae82486d72 fix: cannot open item sidebar after closing with 'X' button (#2241)
When closing an item (component, unit, section, container, etc) sidebar, and trying to reopen it inmediately by clicking the card, it was not opening because navigateTo was being used, but the URL already was the same you were being navigated to. So we also have to update the sidebar item info in the sidebar context in order for it to reopen properly.
2025-07-04 04:38:37 -05:00
Muhammad Faraz Maqsood
dd2853900b feat: apply 2 column format for P&R page widgets 2025-07-04 10:40:15 +05:00
Rômulo Penido
2533724203 fix: increase sidebar width to prevent menu overflow (#2247) 2025-07-03 03:27:01 -05:00
Chris Chávez
ffd430d321 fix: Update add content existing content icons in section/subsection pages (#2224) 2025-07-03 02:36:19 -05:00
Muhammad Faraz Maqsood
ad62519af7 fix: publish btn doesn't show after component edit
When we edit & save the component, publish button doesn't show up until we refresh the page manualy or open this unit by opening previous unit and coming back to this unit again.
In this commit, we are dispatching a storage event whenever we edit the component, it'll refresh the page & show the publish button as expected.
2025-07-01 15:19:39 +05:00
Daniel Valenzuela
76b5dd5925 fix: delete and remove modals styling (#2243) 2025-06-30 15:49:25 -05:00
Navin Karkera
701e41b664 fix: invalidate library queries on restore container (#2231)
Restoring containers should invalidate queries in the library to show the deleted component without needing to refresh.
2025-06-30 15:30:48 -05:00
Rômulo Penido
ac9faacc4d feat: add ParentBreadcrumbs component [FC-0090] (#2223)
Adds the `ParentBreadcrumbs` component to show a list of parent containers on the Unit and Subsection breadcrumbs.
2025-06-30 12:30:48 -05:00
renovate[bot]
37313b30bd chore(deps): update dependency @types/lodash to v4.17.19 (#2239)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-30 01:25:47 -07:00
edX requirements bot
6f79e4475d chore: update browserslist DB (#2238)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-06-30 00:22:35 +00:00
Daniel Valenzuela
e2da13d129 feat: remove unit/subsection from subsection/section (#2149)
Let the user remove a unit/subsection from a subsection/section.
2025-06-27 08:08:40 -05:00
Daniel Valenzuela
aeefcc639f fix: open section/unit with keyboard inside section/subsection page (#2209)
When selecting a unit/subsection inside a subsection/section with the keyboard, opening it in the sidebar by pressing enter was not working.
2025-06-25 12:06:33 -05:00
Navin Karkera
4905f3bbc7 feat: container delete confirmation modal (#2145)
Update container delete confirmation modal based on #1982 and #1981
2025-06-24 12:37:14 -05:00
Brayan Cerón
60cebf703d fix: clear selection on files & uploads page after deleting (#2056)
* refactor: remove selected rows when deleting or adding elements

* refactor: ensure unique asset IDs when adding new ones

* refactor: remove unnecessary loading checks in mockStore function

* test: add unit tests for TableActions component
2025-06-24 08:19:36 -07:00
jacobo-dominguez-wgu
71fa247c61 test: replacing snapshot tests with RTL tests part 11 (#2214) 2025-06-24 03:04:03 -07:00
renovate[bot]
31fc0453b4 chore(deps): update dependency @types/react to v18.3.23 (#2212)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-24 10:03:43 +00:00
renovate[bot]
75137bc651 chore(deps): update dependency @types/lodash to v4.17.18 (#2211)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-24 10:03:31 +00:00
jacobo-dominguez-wgu
085cd7d05c test: replacing snapshot tests with RTL tests part 10 (#2207) 2025-06-24 02:50:54 -07:00
Muhammad Faraz Maqsood
810dd420fd fix: course optimizer styling 2025-06-24 12:51:41 +05:00
Jillian
747f7b6133 Add subsection/unit to section/subsection full-page view within library [FC-0090] (#2152)
* Removes the "content type" tab bar from the "Add Existing Component/Unit/Subsection" modal, and in all cases where only one type of content is shown for selection.
* Updates the section/subsection sidebar to show "Existing Library Content" + "New Subsection" / "New Unit" buttons.
* Updates the "Add New Unit/Subsection" buttons to directly launch the new container modal, instead of going via the container sidebar.
* Ensures that whenever a subsection/unit is created from within a section/subsection, that it is linked to the parent section/subsection after created.
2025-06-24 02:05:35 -05:00
Chris Chávez
ebf4b7c162 feat: Open Manage tags on click tag count in section/subsection page [FC-0090] (#2136)
Add functionality to open the manage tags when clicking the tag count in the section/subsection page.
2025-06-23 12:11:09 -05:00
jacobo-dominguez-wgu
962b30bed9 test: replacing snapshot tests with RTL tests part 9 (#2206) 2025-06-20 12:05:34 -07:00
Chris Chávez
75ea7500e1 fix: Rename optimistic update in children containers (#2141)
Fix: When you update the title of a unit/subsection in the subsection/section page, the text returns to the previous value for a while
2025-06-19 16:11:13 -05:00
jacobo-dominguez-wgu
08c3d123d8 test: replacing snapshot tests with RTL tests part 7 (#2181) 2025-06-19 09:11:51 -07:00
Devasia Joseph
920f4a54e1 fix: TNL-10093 Removed inaccurate course rerun message 2025-06-19 14:49:50 +05:00
renovate[bot]
d9e1a4dea6 chore(deps): update dependency @openedx/frontend-build to v14.6.1 (#1561)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-18 15:31:30 -07:00
renovate[bot]
8b9a80eb04 chore(deps): update dependency @tanstack/react-query to v4.40.0 (#2155)
* fix(deps): update dependency @tanstack/react-query to v4.40.0

* fix: npm was trying to install react-native which conflicted with React 18

The problem is that react-query 4.40.0 specifies an optional, unpinned peerDependency on react-native, and then it depends on @types/react 19, causing a conflict with our React 18. Putting an explicit dependency on the React types solves this. As would upgrading to React Query v5.

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Braden MacDonald <braden@opencraft.com>
2025-06-18 22:12:04 +00:00
jacobo-dominguez-wgu
a5c17452e7 test: replacing snapshot tests with RTL tests part 8 (#2184) 2025-06-18 15:09:21 -07:00
renovate[bot]
4b4ab92383 chore(deps): update dependency redux to v4.2.1 (#1936)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-18 21:51:17 +00:00
Chris Chávez
97710c262e fix: Truncated text in InplaceTextEditor [FC-0090] (#2146)
* Fix the truncated text in InplaceTextEditor.
* Fix the truncated text in the breadcrumbs in the subsection page
2025-06-18 21:38:17 +00:00
Muhammad Faraz Maqsood
b510b6f69f fix: update advanced module list not working (#2189)
Backend was still expecting `{'advanced_modules', {'value': ['poll', 'problem-builder', 'h5pxblock']}}` but without this change, it was receiving `{'advancedModules', ['poll', 'problem-builder', 'h5pxblock']}`

Follow up to https://github.com/openedx/frontend-app-authoring/pull/1581

Co-authored-by: Muhammad Faraz  Maqsood <faraz.maqsood@A006-01130.local>
2025-06-18 13:33:03 -07:00
Kyle McCormick
488173ebdb fix: Subsections should come before Sections 2025-06-18 12:19:50 -07:00
Brian Smith
5a84d8c52f feat!: add design tokens support (#2187)
BREAKING CHANGE: Pre-design-tokens theming is no longer supported.

Co-authored-by: Diana Olarte <diana.olarte@edunext.co>
2025-06-18 15:17:18 -04:00
Daniel Valenzuela
ac7f90065d feat: create subsections, units from within containers (#2104)
Functionality to create subsections, and units from within sections, and subsections respectively.
2025-06-18 12:58:03 -05:00
jacobo-dominguez-wgu
19f81cc05d test: replacing snapshot tests with RTL tests part 6 (#2173)
* test: replacing snapshot tests with rtl tests part 6

* fix: removing testing purposed text

* test: fixing test mocking issues
2025-06-17 12:29:34 -07:00
Jillian
fa9d66c5e5 fix: show "This <containerType> is empty" (#2157)
Shows "This is empty" text when container child list is empty for units, subsections, and sections.
2025-06-16 17:09:55 -05:00
renovate[bot]
dc16b226f0 chore(deps): update dependency @openedx/paragon to v22.20.2 (#2150)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-16 17:12:41 +00:00
jacobo-dominguez-wgu
cba4e684ab test: replacing snapshot tests with RTL tests part 5 (#2143)
* test: replacing snapshot tests with rtl tests part 5

* test: removig extra tests

* test: snaps update

* test: adding import shorthand and turning tests into ts

* docs: clarify which line the comment is about

---------

Co-authored-by: Braden MacDonald <braden@opencraft.com>
2025-06-16 16:56:59 +00:00
renovate[bot]
96df339be5 chore(deps): update dependency @types/lodash to v4.17.17 (#2154)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-16 09:54:23 -07:00
Muhammad Faraz Maqsood
eaee5257bd fix: disable tolerance for multiple answers
As tolerance was being only applied to first correct answer. So, disable tolerance and do not apply it in case of multiple correct answers for Numerical input problem type according to the given documentation: https://docs.openedx.org/en/latest/educators/how-tos/course_development/exercise_tools/manage_numerical_input_problem.html#add-a-tolerance:~:text=hints%20to%20problems.-,Add%20Multiple%20Correct%20Responses%20via%20the%20Advanced%20Editor,text%20string%20as%20correct%20answers.
2025-06-16 11:10:57 +05:00
edX requirements bot
154b411ad8 chore: update browserslist DB (#2153)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-06-16 00:22:22 +00:00
José Ignacio Palma
284e9c7d68 fix: advanced-settings api should not camel-case return value (#1581) 2025-06-13 23:54:32 +00:00
bydawen
fcf1e5cb33 fix: Text truncate issue in the search modal (#2137) 2025-06-13 16:28:29 -07:00
jacobo-dominguez-wgu
2e9b5b7e78 test: replacing snapshot tests with RTL tests part 3 (#2134)
* test: replacing snapshot tests with rtl tests part 3

* test: addint alt text to icon buttons and test refactor
2025-06-13 09:05:48 -07:00
renovate[bot]
8a423ebf10 chore: update dependency yup to v0.32.11 (#1937) 2025-06-12 15:50:38 -07:00
renovate[bot]
b6db457c6f chore: update dependency @edx/browserslist-config to v1.5.0 (#1562) 2025-06-12 22:47:12 +00:00
renovate[bot]
80dabca88e chore: update dependency @edx/frontend-platform to v8.4.0 (#2086)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-12 15:32:22 -07:00
renovate[bot]
376414a653 chore: update dependency @openedx/paragon to v22.20.1 (#2023)
* fix(deps): update dependency @openedx/paragon to v22.20.1

* fix: minor type warnings from new Paragon version

* test: update snapshot test

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Braden MacDonald <braden@opencraft.com>
2025-06-12 15:29:01 -07:00
jacobo-dominguez-wgu
ca85ca8e4b test: replacing snapshot tests with RTL tests part 4 (#2135)
* test: replacing snapshot tests with rtl tests part 4

* test: removing not needed icon mocks, and changing name to render function for editors
2025-06-12 14:12:28 -07:00
Braden MacDonald
4a1f454855 fix: searching "all courses" from studio home wasn't working (#2083) 2025-06-12 09:25:31 -07:00
Chris Chávez
4adf2ff087 fix: Refresh section list on subsection page (#2103)
Invalidates the query in the subsection page used to get the list of sections that contains the subsection
2025-06-12 00:57:25 +00:00
Chris Chávez
569a981a85 fix: show unit published name in sidebar on content picker (#2100)
Fix the bug for show unit published name in sidebar on content picker.
2025-06-12 00:48:56 +00:00
jacobo-dominguez-wgu
3097976b7b test: replacing snapshot tests with RTL tests part 2 (#2132) 2025-06-11 10:15:59 -07:00
Diana Villalvazo
acef2e70cc fix: remove icon and empty breadcrumb from libraries (#2129) 2025-06-11 09:36:45 -07:00
Jillian
c1d874f94f fix: show Preview tab in sidebar when container child selected [FC-0090] (#2128)
Shows the sidebar Preview tab when a container child is selected, while hiding the Preview tab when sidebar shows the container itself, since it's "preview" is already in the main page body.

Adds tests to ensure this behavior is maintained.
2025-06-10 20:05:11 -05:00
jacobo-dominguez-wgu
dc16c42746 test: replacing snapshot tests with RTL tests part 1 (#2108)
* test: replacing snapshot tests with rtl tests part 1

* test: using screen to query and refactor some tests
2025-06-10 15:09:19 -07:00
Ihor Romaniuk
ea33c15b36 fix: remove an extra editing xblock modal on unit page (#2111) 2025-06-10 10:11:01 -07:00
Muhammad Anas
d440394067 fix: remove duplicate markdown_edited save request (#2112)
Removes the unnecessary duplicate save  request of markdown_edited
value to the backend.

Part of: https://github.com/openedx/frontend-app-authoring/issues/2099
Will be backported to Teak.
2025-06-10 11:59:23 -04:00
Arunmozhi
73ac6d725a feat: add v2 CourseAuthoringUnitSidebarSlot (#2000) 2025-06-10 11:46:27 -04:00
Chris Chávez
0e2cab2838 fix: Issue on the in-place editor when renaming library containers (#2101)
* fix: Rename icon size & make the button disappear while editing

* style: Use the correct type in useUpdateContainer
2025-06-09 13:48:51 -07:00
Jillian
b3605fa1b8 refactor: make the unit sidebar code work for any type of container [FC-0090] (#2066)
Refactors the library sidebar and unit info code to make it work for subsections and subsections too
2025-06-09 17:28:58 +00:00
Chris Chávez
be13c18e5d feat: Section/Subsection Card Preview [FC-0090] (#2057)
Section/Subsection card previews
2025-06-09 11:10:18 -05:00
edX requirements bot
019eede7c2 chore: update browserslist DB (#2105)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-06-09 00:22:11 +00:00
Braden MacDonald
5991fd3997 refactor: Load waffle flags using React Query (#2068)
* refactor: use React Query to load waffle flags

* test: add test case

* fix: more clear handling of data loading and fallbacks

* refactor: simplify handling of useReactMarkdownEditor

* test: use new mockWaffleFlags() helper

* test: simplify test mocks in hooks.test.js

* refactor: avoid duplicating flag names, clarify how defaults work
2025-06-05 11:02:57 -07:00
Ihor Romaniuk
9a2dac6d4b fix: load sequences in unit page (#1867)
This handles loading errors when opening the course unit page via direct link as an unauthorized user.
2025-06-05 09:39:43 -03:00
jacobo-dominguez-wgu
061855c31e feat: update to latest footer component, remove broken links (#2072) 2025-06-04 16:17:13 -07:00
diana-villalvazo-wgu
5df4cd941d fix: refactor best practices checklist logic (#2038)
The Best Practices Checklist behavior was wrong for some cases:

* Video: if duration is null it shouldn't be marked as completed
* Video: if there are no videos it shouldn't be marked as completed
* Unit depth: if course doesn't have units it shouldn't be marked as completed
* Diverse learning sequence: description mentions that 80% should contain multiple content types, so if it is exactly 80% it should be marked as completed
2025-06-04 16:46:01 -03:00
Adolfo R. Brandes
7274316eb8 chore: Remove extraneous config file 2025-06-04 16:31:32 -03:00
diana-villalvazo-wgu
151b3e30bf fix: files & uploads menu was truncated due to overflow-x (#2071) 2025-06-04 10:45:22 -07:00
Navin Karkera
dd6780ff41 feat: library section and subsection page (#2032)
* Adds section and subsection library pages. 
* Refactors routing to support them and fix routing from collections page to other pages.
* Refactors library context to reliably set component, unit, and other container ids even when the url changes when user goes back in history rapidly.
2025-06-04 17:32:29 +00:00
Muhammad Anas
99e11d3534 fix: markdown editor issues in modal (#2074)
This PR resolves rendering issues with the Markdown editor inside the modal.
The problem began after a PR [1] introduced the use of modals for the editor.
The EditorPage [2] component expects a `isMarkdownEditorEnabledForCourse` prop,
which was missing in that implementation.

[1] https://github.com/openedx/frontend-app-authoring/pull/1838 
[2] https://github.com/openedx/frontend-app-authoring/pull/1838/files#diff-147218ef88726880178ea895988a5d3feaf2c0c4459086a8de7a4080cbe37de7R226
2025-06-04 12:13:55 -04:00
Victor Navarro
ee7992bde5 fix: Expand all now expands subsections (#1998)
* fix: Expand all now expands subsections

* fix: test cases
2025-06-04 13:02:41 -03:00
Braden MacDonald
1dee2bba58 test: refactor many test suites to use testUtils/initializeMocks (#2067)
Simplifies a bunch of test code by converting it to use our handy testUtils module.

None of the app code is change, just test code. And none of the test cases are modified in any meaningful way - this just simplifies the setup/cleanup significantly.
2025-06-03 15:52:56 -05:00
dependabot[bot]
d806b6150d chore(deps): bump tar-fs (#2069)
Bumps  and [tar-fs](https://github.com/mafintosh/tar-fs). These dependencies needed to be updated together.

Updates `tar-fs` from 2.1.2 to 3.0.9
- [Commits](https://github.com/mafintosh/tar-fs/compare/v2.1.2...v3.0.9)

Updates `tar-fs` from 3.0.8 to 3.0.9
- [Commits](https://github.com/mafintosh/tar-fs/compare/v2.1.2...v3.0.9)

---
updated-dependencies:
- dependency-name: tar-fs
  dependency-version: 3.0.9
  dependency-type: indirect
- dependency-name: tar-fs
  dependency-version: 3.0.9
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-03 10:12:59 -07:00
Muhammad Faraz Maqsood
c7f3e26798 feat: keep content inside the card 2025-06-03 15:11:04 +05:00
Muhammad Faraz Maqsood
27a2b1235e feat: align icons and re-design sections layout
- TNL-11990: Icons Alignment
- TNL-11982: Re-design Sections layout
2025-06-03 15:11:04 +05:00
Muhammad Faraz Maqsood
3c69733170 feat: add sections filter & UI changes
- TNL-11973: Previously Filters functionality was only working for subsections and units inside sections. Now sections are also filtered.
- TNL-11974: New request, Show "no results found" if no results match the filters
- TNL-11975: UI Change, Align filter menu popup to left side of filter button
- TNL-11976: UI Change, Remove underline below "Course optimizer" title
- TNL-11978: UI Change, Change title to "Scan my course"
- TNL-11989: UI Change, Use empty space to display link, don't truncate text before the space runs out
- TNL-11977: New request, Remove this stuff(scanning steps) when scan is complete, it'll disappear after 2.5 seconds
- TNL-11979: UI Change, Move "This tool will scan your course..." text inside of Scan card
- TNL-11980: UI Change, Move "Last scanned on..." date text below Scan button
- TNL-11981: UI Change, Remove icon from "Start scanning" button
- TNL-11983: UI Change, "Start scanning" button should be smaller, made it medium sized
- TNL-11984: UI Change, Remove dividing line under subsection name in expanded card
- TNL-11985: UI Change, Fix alignment of dividing lines, links, and icons in expanded cards to match Figma.
- TNL-11986: UI Change, Match color of the broken icon with other Icons
- TNL-11987: UI Change, Fix alignment of Filter chips to match Figma
- Also added Beta Badge for course optimizer.
- Added tests for codecov coverage
2025-06-03 15:11:04 +05:00
Rômulo Penido
cfb4944d43 feat: refactor library routes and add section/subsection tabs (#2039)
Adds the "Section" and "Subsections" tabs to the library authoring and refactors our library router hook to fix some ambiguities and solve some bugs.
2025-06-02 14:05:31 -05:00
Tony Busa
17e514f937 Add html lang prop to CodeEditor Component inside the SourceCodeModal (#2043) 2025-06-02 09:18:38 -04:00
Muhammad Faraz Maqsood
0c7cef66ab feat: fix toolbar of text editor at top while scrolling 2025-06-02 09:40:33 +05:00
edX requirements bot
c677e7fef3 chore: update browserslist DB (#2058)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-06-02 00:21:33 +00:00
diana-villalvazo-wgu
50cb8608c4 feat: add library name to review updates block card (#2037) 2025-05-30 22:04:02 +00:00
Brayan Cerón
5bb8a5d47c refactor: remove references of ENABLE_HOME_PAGE_COURSE_API_V2 (#1611)
* refactor: remove references of ENABLE_HOME_PAGE_COURSE_API_V2
* fix: infinite requests when clearing filters
* fix: some requests were being duplicated when changing filters
* test: adapt tests to the latest changes
* test: improve test coverage
* refactor: drop tab for archived courses
* test: filter reset functionality in CoursesTab component
* refactor: revert deletion of isShowProcessing
* test: update visibility check for pagination text in TabsSection tests
* refactor: update dropdown and button accessibility in CardItem and CoursesTab components
2025-05-30 14:31:47 -07:00
Braden MacDonald
f02347dd71 perf: only import JSZip when needed (bundle splitting) (#1933) 2025-05-30 09:45:20 -07:00
Maria Grimaldi
0eaa7f6f88 fix: add file extension to .yml 2025-05-30 08:31:53 -04:00
Maria Grimaldi
e6c1c95260 refactor: use workflow from .github repo 2025-05-30 08:13:39 -04:00
Maria Grimaldi
a18444e691 chore: add workflow to pull release testing issues into the BTR board 2025-05-30 08:13:39 -04:00
Maria Grimaldi
5561c030e8 chore: add workflow to pull release testing issues into the BTR board
Add GH workflow that includes issues into the BTR board after the issue
is labeled with `release testing`.  Also add label needs triage for
bug triaging issues.
2025-05-30 08:13:39 -04:00
Rômulo Penido
fffa9e2566 fix: selection card wiggle (#2045)
Removes the library cards' resize because of the border change on selection.
2025-05-29 18:54:02 +00:00
Rômulo Penido
f18274533e fix: set unit preview readonly on sidebar (#2008)
Make the unit preview on the sidebar read-only and add `Truncate` to the `InplaceTextEditor`
2025-05-29 13:33:23 -05:00
Jillian
3fc0f27d67 fix: upstreamInfo is not always provided (#2041) 2025-05-29 10:58:20 -05:00
sundasnoreen12
36e57a0cfb fix: passed course id and fixed test cases 2025-05-29 08:53:47 +05:00
Navin Karkera
afd6afdbb9 feat: create section and subsection in library (#2013)
Adds create section and subsection buttons in sidebar.
2025-05-28 16:10:17 -05:00
Braden MacDonald
01243afdd9 chore: bump UUID to v11 (#1932) 2025-05-27 13:08:24 -05:00
diana-villalvazo-wgu
b0e194e512 fix: Display "details" tab as default in collections (#2027) 2025-05-26 15:59:30 -07:00
Daniel Valenzuela
260582b6f0 fix(search-manager): send search keywords to facet search too (#2020)
Filter counts depends on the response for the meilisearch faceted search. Since the search keywords affect the search results, in order to make the block type filter counts reflect the search results, we need to include the search keywords into the faceted search too.
2025-05-26 13:54:54 -05:00
sundasnoreen12
ce337aedef test: added test case 2025-05-26 13:31:04 +05:00
sundasnoreen12
44d47f8783 fix: removed commented line 2025-05-26 13:31:04 +05:00
sundasnoreen12
65c8b8ba4b test: fixed test case issue 2025-05-26 13:31:04 +05:00
sundasnoreen12
80dba704da fix: fixed spacing issues 2025-05-26 13:31:04 +05:00
Ahtisham Shahid
9906901262 fix: updated failing tests 2025-05-26 13:31:04 +05:00
Ahtisham Shahid
5167b167eb feat: added process to sync discussions topic on page load
feat: added process to sync discussions topic on page load

fix: updated failing unit tests

feat: added course creation date in index api

feat: added course creation date in index api

fix: updated unit tests
2025-05-26 13:31:04 +05:00
Muhammad Faraz Maqsood
951b707c7d fix: increase max value for the grace period
- increase max value for the grace period as same as it was before in the legacy experience
2025-05-26 11:03:46 +05:00
dependabot[bot]
8e1e2fdb46 build(deps): bump codecov/codecov-action from 4 to 5
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4 to 5.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-26 10:51:26 +05:00
edX requirements bot
ca8ce5b253 chore: update browserslist DB (#1997)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-05-26 00:21:21 +00:00
Jillian
c5f7d0cf3b fix: set maxHeight on TextEditor TinyMce widget [FC-0090] (#2024)
Sets a max_height=500px for the TinyMCE editor when editing a Text/Html component.
This prevents the autoresize plugin from expanding the editor textarea beyond the bounds of the editor modal.

⚠️ Because the max height can only be a numeric pixel value, we can't use clever settings like vh or %, and so we're forced to limit the height of the editor to a fixed size for all screen sizes in order to address this issue.
2025-05-23 13:51:39 -05:00
Jillian
ac5574d2c4 fix: refresh xblock inline after accepting/rejecting library sync (#2022)
Instead of reloading the entire Unit after syncing changes from the
library, just reload the xblock that was changed.
2025-05-22 10:49:23 -05:00
Muhammad Faraz Maqsood
df3577241f fix: studio time zone conversion issue 2025-05-22 10:32:41 +05:00
Chris Chávez
65605bf937 fix: Remove never published filter from component picker (#1947)
Removes the never-published filter option from the component picker and unit picker.
2025-05-22 00:37:42 +00:00
Rômulo Penido
9e978057bc fix: rename library publish button to "Publish All" (#2016)
renames the Library publish button from "Publish All Changes" to "Publish All"
2025-05-21 18:12:17 -05:00
diana-villalvazo-wgu
279a900a10 fix: rename "updates" and "libraries" menu items for clarity (#2004) 2025-05-21 11:46:29 -07:00
jacobo-dominguez-wgu
f2d5bc4680 fix: removing edX text reference on video fallback message (#1996) 2025-05-21 11:41:58 -07:00
Chris Chávez
ee5e51d371 fix: Inconsistent publish status filter menu placement (#1966) 2025-05-21 10:22:34 -07:00
Chris Chávez
0e40aa295d feat: New confirmation modal when deleting library components (#1906)
* feat: New units message on delete confirm modal when deleting components
* test: Tests for new delete confirmation messages
* refactor: useComponentsFromSearchIndex added
* refactor: Move fetch units to ComponentDeleter
* style: Delete unnecessary code
2025-05-21 10:04:19 -07:00
Rômulo Penido
e212e1a1ef fix: rename library publish button (#1993)
This PR renames the Library publish button from "Publish" to "Publish All Changes"
2025-05-20 18:22:51 -05:00
Daniel Valenzuela
1568067980 fix: do open editor of new xblock when duplicating (#1887)
Fixes bug where after duplicating an xblock, the editor modal of the old xblock is being open instead of the new copied xblock.
2025-05-20 17:51:42 -05:00
Navin Karkera
503642be8c feat: open collection or unit page on double click only (#2002)
Opens collection or unit page only on double click.
2025-05-20 15:34:03 -05:00
Navin Karkera
6f3b7ab962 fix: search text flickering (#1999)
Fix flickering issue in search field.
2025-05-19 12:30:16 -05:00
Navin Karkera
08ac1c0c4d feat: select component and show sidebar on edit (#1949)
Select component that is being edited in library and show its sidebar. Also fixes issue with children component listing in library unit page
2025-05-19 12:24:14 -05:00
Rômulo Penido
6a3b0064ff fix: change InplaceTextEditor style and add optimistic update (#1953)
* Optimistic update for renaming Components, Collections and Containers
* Change the InplaceTextEditor to show the new text until the onSave promise resolves
* Change the InplaceTextEditor style to: Always show the rename button
2025-05-19 11:46:54 -05:00
renovate[bot]
1d45fa2e38 fix(deps): update dependency @edx/frontend-platform to v8.3.7 (#1469)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-19 09:40:50 -04:00
Muhammad Faraz Maqsood
62bffc06d7 feat: add never show assessment msg in subsection
- add never show assessment result message in subsection card
2025-05-19 09:06:50 +05:00
jacobo-dominguez-wgu
88aa4c1524 fix: various additional i18n issues
* fix: adding messages for i18n issues related to aria labels

* fix: replacing ternary operator

* refactor: injecting intl object to prevent extra modifications on license details component

* test: fixing failing snapshot test

* chore: best descriptions to aria label and removing aria label not needed

* test: snapshot update and fixing ut

* chore: best descriptions to aria labels
2025-05-13 20:14:14 +00:00
Braden MacDonald
4ebc1590e7 docs: update maintainer to me in catalog-info.yaml
https://discuss.openedx.org/t/frontend-app-authoring-maintanership-transfer/15786
2025-05-13 13:14:05 -07:00
Navin Karkera
97e5fbaa5e chore: add comment to prevent course search reload on type 2025-05-13 11:34:27 -07:00
Ivo Branco
03a757de21 fix: include plugins in i18n extraction script (#1802)
Add the additional source `plugins` folder on the `fedx-scripts` extract translations.
This can be configured because the frontend-build v14.5.0 now supports additional source folders using the `--include` extra argument.
2025-05-13 12:56:11 -04:00
Braden MacDonald
d8eda2494b chore: remove unused dependencies "npm" and "start" (#1931) 2025-05-12 15:24:29 -05:00
jacobo-dominguez-wgu
db07092880 fix: various i18n issues
* fix: adding messages for i18n issues related to placeholders

* fix: adding messages for i18n issues related to import tag wizard stepper titles

* fix: changing name to duplicated id on i18n message

* fix: replacing hardcoded string with constants to solve i18n issue

* fix: typo on title prop

* fix: adding components prop name correctly

* test: adding ut for select video modal

* chore: adding description to placeholder, changing extension to constant file and adding uts for code coverage

* chore: removing outdated comment lines
2025-05-12 09:49:03 -07:00
Navin Karkera
26c6a71624 fix: search modal refresh on typing (#1938)
The whole page was being refreshed while searching content from course
outline page due to fetching of waffle flag on changes in location
search field.
2025-05-12 11:42:59 -05:00
Rômulo Penido
d5dc8b5ebe fix: review/sync bugs [FC-0083] (#1905)
Fixes issues related to component libraries' review/sync flow

* Inconsistent sync pane title versions
* Library content shown in preview warning only appears in review changes modal when that modal is opened from the review tab
* Some new changes only appear within library review tab on scroll at top of list
* Vertically misaligned sync icon in review changes message on course outline
* Show available updates whenever content is updated, regardless of number of updates available
2025-05-12 09:57:38 -05:00
Chris Chávez
7b2cc125a5 fix: Issue with read-only units in libraries & published version of units in library units picker [FC-0083] (#1926)
Fixes the issues from https://github.com/openedx/frontend-app-authoring/issues/1633#issuecomment-2828953801

* In successfully added units, the "add new component" widget appears sometimes
* In the "add existing unit" modal, the preview shows draft versions of units
2025-05-12 09:45:46 -05:00
edX requirements bot
9a2dc8061a chore: update browserslist DB (#1935)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-05-12 00:21:47 +00:00
Rômulo Penido
cc47616256 fix: improve focus/selected style on library authoring (#1918)
Improves the focus and selected styles from the LibraryPage and UnitPage.
2025-05-09 11:05:03 -05:00
Muhammad Faraz Maqsood
e8463f7a6a feat: add more unit tests for code coverage
- add more unit tests for code coverage to cover more use cases
- ignore Modal close in code coverage as our modal does not have close button
2025-05-09 11:28:21 +05:00
Muhammad Faraz Maqsood
c77c4f3c91 feat: add unit tests for filter functionality 2025-05-09 11:28:21 +05:00
Muhammad Faraz Maqsood
36277d8ef5 feat: course optimizer page better design
- Add filter functionality to course optimizer broken links to check different results
- modify design, make use of logo with better tooltip
- change message texts in different area of the page
2025-05-09 11:28:21 +05:00
Braden MacDonald
cdb8016657 fix: invalidate search results when publishing all changes in library (#1925) 2025-05-08 17:28:07 -05:00
Navin Karkera
8c3fab3792 fix: UX issues in unit page (#1913)
Fixes the following issues:

* Selection behavior
* Component selection is by header click only
* Newly created blocks within a unit should be selected on creation/save, appear selected, and have their sidebar open
* Some long text components seem to display at the default height rather than a longer height
* Within the full-page unit view, the "add to collection" overflow menu item on components does not seem to work/only opens the sidebar.
* Draft status indicator text is not vertically centered with icon
* When reordering, dragging a short component past a long component often causes a strange stutter effect.
* When dragging to reorder a component, moving quickly or scrolling often causes the drag handle to be lost / causes the block to jump somewhere else
* Reordering may not consistently support a keyboard-accessible option to change order, like in course authoring
* Tag button on component header opens the old tag side pane
2025-05-07 17:30:25 -05:00
Ihor Romaniuk
04e8f3a488 fix: manage access modal on duplicated xblock (#1866) 2025-05-07 15:40:09 -03:00
Rômulo Penido
d7173036a5 fix: unit pages ux bugs [FC-0083] (#1884)
This PR fixes some UX bugs related to the unit pages:

* Sort for "recently modified" on unit tab does not update after adding new components to units
* Change component delete warning message
2025-05-06 20:34:07 -05:00
edX requirements bot
208b0c9195 chore: update browserslist DB (#1907)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-05-05 00:21:37 +00:00
Jillian
24e469542d perf: use Library search results to populate container card preview (#1820)
* fix: use Library search results to populate container card preview

* feat: show published children when showing only published Unit content

* fix: nits
2025-05-01 19:13:43 -07:00
Rômulo Penido
0fdc460c5b fix: several library unit page UX bugs (#1868)
* fix: rename "Organize" tab to "Manage"

* fix: duplicate key warnings

* fix: uniform messages while adding to collection

* fix: do not allow units be added to a unit
2025-05-01 15:31:43 -07:00
renovate[bot]
a7b10495e6 fix(deps): update dependency react-textarea-autosize to v8.5.9 (#1769)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-01 15:34:49 -04:00
renovate[bot]
fdfc30dbd5 fix(deps): update dependency react-select to v5.10.1 (#1787)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-01 15:20:12 -04:00
dependabot[bot]
75e0531c5b chore(deps): bump @babel/helpers from 7.25.0 to 7.27.0 (#1763)
Bumps [@babel/helpers](https://github.com/babel/babel/tree/HEAD/packages/babel-helpers) from 7.25.0 to 7.27.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.27.0/packages/babel-helpers)

---
updated-dependencies:
- dependency-name: "@babel/helpers"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 15:02:15 -04:00
dependabot[bot]
b697a44f36 chore(deps): bump http-proxy-middleware from 2.0.7 to 2.0.9 (#1840)
Bumps [http-proxy-middleware](https://github.com/chimurai/http-proxy-middleware) from 2.0.7 to 2.0.9.
- [Release notes](https://github.com/chimurai/http-proxy-middleware/releases)
- [Changelog](https://github.com/chimurai/http-proxy-middleware/blob/v2.0.9/CHANGELOG.md)
- [Commits](https://github.com/chimurai/http-proxy-middleware/compare/v2.0.7...v2.0.9)

---
updated-dependencies:
- dependency-name: http-proxy-middleware
  dependency-version: 2.0.9
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 14:52:19 -04:00
dependabot[bot]
db0f562d93 chore(deps): bump formidable from 3.5.2 to 3.5.4 (#1877)
Bumps [formidable](https://github.com/node-formidable/formidable) from 3.5.2 to 3.5.4.
- [Release notes](https://github.com/node-formidable/formidable/releases)
- [Changelog](https://github.com/node-formidable/formidable/blob/master/CHANGELOG.md)
- [Commits](https://github.com/node-formidable/formidable/commits)

---
updated-dependencies:
- dependency-name: formidable
  dependency-version: 3.5.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 14:42:16 -04:00
renovate[bot]
11835d28aa fix(deps): update dependency @edx/openedx-atlas to ^0.7.0 (#1855)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-01 13:55:41 -04:00
renovate[bot]
b023173ed4 fix(deps): update dependency @codemirror/view to v6.36.6 (#1315)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-01 13:40:13 -04:00
Navin Karkera
bc18fffedf refactor: remove custom order function from course libraries list (#1865) 2025-04-30 13:41:17 -07:00
Jansen Kantor
484154b9bd fix: pages and resources plugins not rendered (#1885) 2025-04-30 15:56:49 -04:00
Muhammad Faraz Maqsood
65aca04708 fix: Error when viewing text component in RAW HTML (#1869) 2025-04-28 16:51:54 -04:00
Ivo Branco
d92b27ee93 fix(i18n): translate files and videos table view (#1591)
Fix translation issue on Files and Videos table view mode on the columns.
2025-04-28 12:38:27 -05:00
Brayan Cerón
0f5c752eb0 fix: update MIME type for tar.gz file acceptance in dropzone (#1862)
This solves an issue that allowed the users to import files .gz.
We make the drop zone allow only .tar.gz files.

Resolves https://github.com/openedx/frontend-app-authoring/issues/1386
2025-04-28 12:45:36 -04:00
Raymond Zhou
3d2df5f4be chore: update readme on legacy flags (#1861) 2025-04-28 11:34:17 -04:00
Daniel Valenzuela
dbb1a996e1 feat: display editors as modals (#1838) 2025-04-25 19:48:28 +00:00
Jillian
b30a1c8c5e fix: NaN library components are out of sync [FC-0083] (#1864) 2025-04-25 10:08:33 -05:00
Chris Chávez
855b44f745 feat: Add 'This unit can only be edited from the library' banner (#1860) 2025-04-24 20:50:29 -07:00
Jillian
2d55ba4ccc fix: allow units sourced from libraries to update their settings (#1863) 2025-04-24 17:58:37 -07:00
Chris Chávez
d62c4cf4f8 feat: Sync units in course outline [FC-0083] (#1850)
* Adds the sync button in unit cards in the course outline.
* Opens the compare previews.
* Functionality to sync units.
* Functionality to decline sync units.
2025-04-24 20:18:04 +00:00
Rômulo Penido
9824502278 feat: disallow edits to units in courses that are sourced from a library (#1833) 2025-04-24 19:20:46 +00:00
Chris Chávez
d6b51ecf0c feat: Add unit from library into course (#1829)
* feat: Initial worflow to add unit to course
* test: Add initial tests
* feat: Show only published units
* test: Update Subsection card test and ComponentPicker tests
* feat: Connect add unit from library API
* test: Test for Add unit from library in CourseOutline
* fix: create a new Vertical from a Library Unit
* docs: add a little note about avoiding 'vertical' where possible
* refactor: Use visibleTabs instead of showOnlyHomeTab

---------

Co-authored-by: Jillian Vogel <jill@opencraft.com>
Co-authored-by: Braden MacDonald <braden@opencraft.com>
2025-04-24 12:07:54 -07:00
Muhammad Faraz Maqsood
1fe1f93314 fix: incorrect video durations (#1856)
- fix: incorrect video durations in video info tab and  videos list view

Co-authored-by: Muhammad Faraz  Maqsood <faraz.maqsood@A006-01130.local>
2025-04-24 13:17:40 -04:00
Brian Smith
fbc1273955 feat: import StudioFooterSlot from component package instead of slot package (#1832) 2025-04-24 12:58:27 -04:00
Brian Smith
7edb3528ba feat: standardize slot ids (#1854) 2025-04-24 07:27:04 -04:00
renovate[bot]
e7c22b1cbf fix(deps): update dependency @edx/frontend-component-header to v6.4.0 (#1790)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-23 16:24:47 -04:00
Muhammad Anas
380f3be164 feat: added markdown editor for editing problems in markdown format (#1805) 2025-04-23 13:24:27 -07:00
Chris Chávez
74d7d66c59 feat: New Transcript widget state on video editors on creation workflow [FC-0076] (#1825)
* New Transcript widget state on video editors on creation workflow
* Which edX user roles will this change impact? "Course Author",
2025-04-23 09:52:10 -05:00
Arunmozhi
e2189f2fdd feat: Enhance Sidebar Slot properties (#1845)
The commit add some extra properties to the CourseAuthoringSidebarSlot
and CourseAuthoringUnitSidebarSlot components to enable
the widgets in the sidebar to have more context to work with.
2025-04-23 09:46:00 -04:00
Muhammad Faraz Maqsood
293b7941dd fix: video & file page toggles
- react redux state changes back to default whenever page refreshes.
 - On course authoring mfe, whenever we redirect from one page to another, it automatically refreshes the page which react app shouldn't do.
 - So, instead of managing video and file pages previously selected view in react redux, save & manage these values in localStorage. So that page refreshes doesn't bother end users.
2025-04-23 12:22:17 +05:00
Rômulo Penido
eaa075464c feat: rename component on library unit page (#1823) 2025-04-22 22:16:38 -07:00
Muhammad Faraz Maqsood
03d732846e fix: TypeError r is not function for custom pages
- fix TypeError r is not a function for custom pages by replacing injectIntl with useIntl() hook.
- fix import for textbooks app
2025-04-23 10:13:45 +05:00
Muhammad Faraz Maqsood
c1302f1089 fix: TypeError r is not a function
- injectIntl is deprecated, Used useIntl() hook instead.
- ErrorLog
```
React Router caught the following error during render TypeError: r is not a function {
  "componentStack": "
    at A (https://course-authoring.edx.org/817.bfc0047cf532fb354633.js:2:5259944)
    at Suspense
    at d (https://course-authoring.edx.org/817.bfc0047cf532fb354633.js:2:65420)
    at t (https://course-authoring.edx.org/817.bfc0047cf532fb354633.js:2:7316739)
    at g (https://course-authoring.edx.org/817.bfc0047cf532fb354633.js:2:8043115)
    at w (https://course-authoring.edx.org/817.bfc0047cf532fb354633.js:2:4746781)
    at div
    at https://course-authoring.edx.org/817.bfc0047cf532fb354633.js:2:6453516
    at div
    at https://course-authoring.edx.org/817.bfc0047cf532fb354633.js:2:7617877
    at div
    at h (https://course-authoring.edx.org/817.bfc0047cf532fb354633.js:2:4740935)
    at rR (https://course-authoring.edx.org/app.756074826164c8adbdbb.js:2:1102691)
    at r (https://course-authoring.edx.org/817.bfc0047cf532fb354633.js:2:1493518)
    at injectIntl(r)
    at main
    at l (https://course-authoring.edx.org/app.756074826164c8adbdbb.js:2:2224276)
    at cR (https://course-authoring.edx.org/app.756074826164c8adbdbb.js:2:1103620)
    at r (https://course-authoring.edx.org/817.bfc0047cf532fb354633.js:2:1493518)
    at injectIntl(r)"
}
```
2025-04-23 10:13:45 +05:00
Chris Chávez
ea26981393 feat: Enable ORA2 in libraries by default (#1847) 2025-04-22 14:34:34 -07:00
Braden MacDonald
55e505eb36 chore: simplify imports in library-authoring/data/apiHooks.ts (#1842)
This just simplifies how API methods are imported into one apiHooks.ts file, reducing the overall lines of code and chance for conflicts. Since we're importing all the API methods anyways, there is nothing to gain from explicitly importing each one separately.
2025-04-22 11:50:06 -05:00
Muhammad Faraz Maqsood
9002f7acfe chore: upgrade footer version 2025-04-22 12:28:18 +05:00
edX requirements bot
febf5cf5d0 chore: update browserslist DB (#1839)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-04-21 00:20:48 +00:00
Raymond Zhou
ac127e2b15 Revert "fix: use navigate instead of Link from react-dom"
This reverts commit 06bdff1796.
2025-04-19 10:26:42 +05:00
Muhammad Faraz Maqsood
06bdff1796 fix: use navigate instead of Link from react-dom
getting TypeError: r is not a function. Replace Link with navigate.
2025-04-18 21:26:22 +05:00
Braden MacDonald
ea0a031d7b feat: button to publish a container [FC-0083] (#1827)
- Publish button with functionality of publish units and components inside the unit
2025-04-18 09:34:46 -05:00
Muhammad Faraz Maqsood
ea8a8e5285 fix: toggle behaviour for video & file view
- fix toggle behaviour for video and file view.
- Before:
  - The default view was card. And The videos and files both pages were sharing same variable & default view.
  - Whenever user selects list view on videos/files page and redirects to another page, the toggle/view shifts again to default(card) view whenever it returns to videos/files page.

- After:
  - The default view is list now. And The videos and files both pages can have different state & default view.
  - Whenever user selects card view on videos/files page and redirects to another page, the toggle/view remain same whatever user had selected before when it returns to videos/files page.

Note: Refreshing a page will use default(list) view.
2025-04-18 11:13:32 +05:00
Chris Chávez
9adfa58d65 feat: Remove component from unit [FC-0083] (#1824)
* Users can remove a component from a unit
* The component is NOT deleted, and remains present in the library
* A toast shows that the component was removed, and allows the user to undo
* Overflow menu item appears in sidebar for selected components in unit
* Overflow menu item appears directly on components in full page unit view
2025-04-17 17:51:42 -05:00
Navin Karkera
4ddb8c3168 feat: edit components in unit page [FC-0083] (#1821)
Allows authors to edit components from unit page. It makes sure that the component preview is updated on save, allows user to double click and open editor in modal etc.
2025-04-17 09:59:16 -05:00
Navin Karkera
3b2adc2fc1 feat: reorder components in unit page [FC-00083] (#1816)
Reorders components in unit page via drag and drop. This PR also refactors and moves draggable list and sortable item components to appropriate location.

Course authors will be affected by this change.
2025-04-16 14:34:28 -05:00
Régis Behmo
4bd2c3b29a feat: lighter build by rewriting lodash imports (#1772)
Incorrect lodash imports are causing MFEs to import the entire lodash
library. This change shaves off a few kB of the compressed build.
2025-04-15 17:07:16 -07:00
Braden MacDonald
f531d5471d fix: merge errors in previous commit (#1819) 2025-04-15 23:46:16 +00:00
Braden MacDonald
f24b89c847 feat: allow pasting units from a course into a library (#1812) 2025-04-15 15:26:19 -07:00
Rômulo Penido
d9dcdfe1e3 feat: add existing components to unit [FC-0083] (#1811)
allows adding existing components to units
2025-04-15 16:49:53 -05:00
Rômulo Penido
990073cb38 feat: renames unit in LibraryUnitPage and adds InplaceTextEditor component (#1810) 2025-04-15 15:42:36 -05:00
Jillian
afecd8ba83 fix: sort Advanced Blocks by default display name (#1817) 2025-04-15 15:07:21 -05:00
Rômulo Penido
aa8a5bfba4 feat: add collections support for containers [FC-0083] (#1797)
Adds support to add Units to Collections.
2025-04-15 13:13:12 -05:00
Navin Karkera
87695ae636 fix: auto adjust min height of xblock previews [FC-0083] (#1813)
Sets minimum height of library block previews based on its render
location and block type.
2025-04-15 10:37:59 -05:00
Braden MacDonald
681854209a fix: Copy to clipboard would seemingly fail even if it worked 2025-04-14 17:21:10 -07:00
Chris Chávez
a522c48045 feat: Add component to Unit [FC-0083] (#1784)
Creation workflow in unit page.
2025-04-14 22:36:46 +00:00
edX requirements bot
f46e4ce4e8 chore: update browserslist DB (#1814)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-04-14 00:21:14 +00:00
Navin Karkera
a43027b328 feat: library unit page skeleton [FC-0083] (#1779)
* View a unit page, which has its own URL
* Components appear within a unit as full previews. Their top bar shows type icon and title on the left, and draft status (if any), tag count, overflow menu, and drag handle on the right.
* Components have an overflow menu within a unit
* Components can be selected within a unit
* When components are selected, the standard component sidebar appears. The preview tab is hidden, since component previews are visible in the main content area.
* Components within a unit full-page view have hover and selected states
* Unit sidebar preview.
* Frontend implementation Drag-n-drop components to reorder them in unit.
2025-04-11 13:50:40 -05:00
Muhammad Anas
01365d080e feat: replace StudioFooter with StudioFooterSlot (#1729) 2025-04-11 13:29:41 -04:00
Chris Chávez
e00a4c4d03 refactor: Build new action buttons for cancel confirmation modal (#1732)
Build new action buttons for cancel confirmation modal in basic block and advanced block editors.
2025-04-11 11:55:32 -05:00
Kshitij Sobti
341a03c50b feat: Add plugin slots for sidebars (#1752) 2025-04-11 07:19:13 -04:00
Chris Chávez
5df7adffec feat: Delete unit [FC-0083] (#1773)
* Adds the delete menu item in unit cards.
* Delete a unit with a confirmation modal.
* Restore a component
2025-04-10 23:59:10 +00:00
Rômulo Penido
04faf54ad8 feat: add container (e.g. unit) tag support (#1782) 2025-04-09 12:10:31 -07:00
Bryann Valderrama
d688cf57b7 fix: add user partition id when update groups 2025-04-09 11:55:11 -07:00
sundasnoreen12
fe36e65d2d fix: removed all varaibles of feedback url 2025-04-09 12:45:56 +05:00
sundasnoreen12
8e99ebf072 test: removed variables from test file 2025-04-09 12:45:56 +05:00
sundasnoreen12
024537c80e feat: hide feedback widget 2025-04-09 12:45:56 +05:00
Muhammad Faraz Maqsood
0ddcbbb7a5 fix: ignore altText to avoid replace &quot; with "
- ignore altText to avoid replacing &quot; with "(double quotes) in alt text value
- modify unit tests to cover this new code
2025-04-09 11:58:22 +05:00
Jillian
7ceeb32820 feat: Unit card previews [FC-0083] (#1774)
Adds block tiles to the Unit card to indicate type and quantity of children in the container.
2025-04-08 17:47:04 -05:00
Sarina Canelake
451b821c3b docs: Update references to docs.edx.org (#1783)
With the transition to docs.openedx.org, update links to docs.edx.org to the community-supported site.
2025-04-07 13:55:19 -04:00
Rômulo Penido
68d62cd62f feat: library unit sidebar [FC-0083] (#1762)
Implements the placeholder for the Unit Sidebar.
2025-04-07 11:51:10 -05:00
Rômulo Penido
2a31434a55 fix: prevent multiple submits while creating units [FC-0083] (#1776)
Fixes a bug where the form is submitted multiple times when the user presses Enter on the Unit create form.

The issue was that when the user hit Enter, the form was submitted without calling the button's onClick, allowing multiple calls. Also, because the onClick was not called, we had to add the isLoading property to the LoadingButton to display the status correctly.
2025-04-07 09:24:51 -05:00
Muhammad Faraz Maqsood
fdd8928f36 feat: add manual check count to collapsed view 2025-04-07 10:40:11 +05:00
Muhammad Faraz Maqsood
552ff395df chore: rename course optimizer name in dropdown 2025-04-07 10:40:01 +05:00
edX requirements bot
c324446722 chore: update browserslist DB (#1785)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-04-07 00:20:14 +00:00
Arunmozhi
15fcb55075 feat: adds slots for in-context metrics in studio outline and unit views (#1725) 2025-04-04 07:29:36 -04:00
Régis Behmo
d1a6af51a4 chore: remove husky 🪓🐶
We remove husky, which is triggering pre-push git hooks, including
running "npm lint". This is causing failures when building Docker
images, because "npm clean-install --omit=dev" automatically triggers "npm
prepare", which attemps to run "husky". But husky is not listed in the
build dependencies, only in devDependencies. As a consequence, package
installation is failing with the following error:

        14.13 > @edx/frontend-app-ora-grading@0.0.1 prepare
        14.13 > husky install
        14.13
        14.15 sh: 1: husky: not found

Similar to: https://github.com/openedx/frontend-app-learning/pull/1622
2025-04-02 14:00:02 -07:00
sarina
55344bc55d docs: Update edx.rtd links to docs.openedx.org 2025-04-02 15:59:31 -04:00
sarina
a23f6a6fa7 docs: Update README: s/devstack/tutor/ 2025-04-02 15:59:31 -04:00
sarina
5cedaacc3e docs: Add note to use .nvmrc node version 2025-04-02 15:59:31 -04:00
Brian Smith
0ce0b7526e feat: upgrade to react 18 (#1766) 2025-04-02 12:04:48 -04:00
Ihor Romaniuk
3685dbd6a1 feat: [FC-0070] rendering split test content in unit page (#1492)
Introduces functionality to display Split Test Content within the new Unit page interface.
2025-04-01 11:37:14 -03:00
Rômulo Penido
272e30f1b1 feat: library units tab (#1754)
Implements the "Units" tab on the Library Authoring.
2025-03-31 13:34:25 -05:00
Rômulo Penido
98ae74e78c feat: unit cards in library [FC-0083] (#1742)
Unit cards in library and rename BaseComponentCard -> BaseCard
2025-03-31 10:54:07 -05:00
Rômulo Penido
df7405ec39 feat: create unit workflow (#1741)
Implements the basic workflow to create a Unit in a Library.
2025-03-28 15:44:58 -05:00
Muhammad Farhan
d497bf2ccc fix: update useRef before dispatching file upload action 2025-03-28 19:38:06 +05:00
Muhammad Faraz Maqsood
94f34074ce fix: link navigation for BrokenLink and GoToBlock
In this commit, Fix link navigation in BrokenLinkHref and GoToBlock components
- Updated BrokenLinkHref to prevent default anchor behavior and open broken links directly in a new tab.
- Updated GoToBlock to prevent default anchor behavior and open block URLs directly in a new tab.
- added test coverage for this fix code in `CourseOptimizerPage.test.js`, this wasn't covered before: https://github.com/openedx/frontend-app-authoring/pull/1760/checks?check_run_id=39390124321
2025-03-28 12:19:29 +05:00
Brian Smith
92a8b42e36 feat(deps): update @openedx dependencies to versions that support React 18 (#1759) 2025-03-27 12:19:00 -04:00
Muhammad Farhan
08368582e3 fix: video ID not populating issue 2025-03-26 23:07:27 +05:00
Navin Karkera
a52f6d9b94 fix: prevent editor from loading twice before initialization (#1761)
Data from previous editor instance was being processed by current editor
instance and sometimes failed due to mismatch. For example, editing text
editor or any other basic editor after opening an advanced problem like
drag-n-drop crashed. Now the editor is only rendered after the
initialization process is complete.
2025-03-25 20:14:57 -05:00
Navin Karkera
bac63583ac refactor: don't dismiss out of sync alert on review (#1750)
Clicking review button on out of sync alert should not dismiss the alert
and it should be displayed again in outline or all tab.
2025-03-24 11:39:10 -05:00
Hina Khadim
545bb4a8a6 feat: add manual check links section separately for 403 links (#1751) 2025-03-24 19:55:56 +05:00
Kyle McCormick
9e65424ca6 refactor: Remove unused defaultToAdvanced and getBetaParsedOLXData (#1753)
edx-platform would pass a default_to_advanced flag in through the REST
API, depending on the value of a waffle flag. The flag did not actually
cause anything to default to advanced. What it actually did was switch
from getParsedOLXData to getParsedBetaOLXData. However, getBetaOLXParser
was never implemented--it just logs a console warning and return
getOLXParser.

We remove this unused flag and unused function.
The underlying default_to_advanced API flag and the backing waffle flag
will be removed from edx-platform in a separate PR.
2025-03-20 15:49:36 -04:00
Navin Karkera
27c4eec746 refactor: open review tab in course libraries if out of sync (#1743) 2025-03-19 12:49:22 -05:00
Muhammad Farhan
cc20dfd8ca fix: fetch only studio home data without courses 2025-03-19 12:57:03 +05:00
Rômulo Penido
a26e3f9e92 fix: show error information when taxonomy import fails (#1730)
Adds the error information when we have a failure while importing a Taxonomy
2025-03-17 10:00:33 -05:00
Navin Karkera
e66da2cb49 fix: image rendering in single and multi select problems (#1731)
Fix images in single and multi select problems in libraries. Found following issues and fixed them:

* Images were not being rendered in any of the fields in these problems.
* Base url was not being set which is used by tinymce to load images with relative path.
* Answer fields were set to inline mode which does not initialize images or base paths
* If same image twice is used twice in a problem, the logic of replacing `static/image.jpg` with `/static/image.jpg` would replace the first occurrence twice resulting in `//static/image.jpg`, breaking both the links.
* On initialization of answer fields, the absolute static asset urls were being replaced by relative urls causing the editor being set as dirty without user changes.
2025-03-13 11:11:44 -05:00
Navin Karkera
77a55d9ad3 feat: course libraries review tab [FC-0076] (#1699)
Adds review tab to course libraries page. Also refactors all libraries page as per new designs.
2025-03-12 12:58:27 -05:00
Chris Chávez
3aa409d065 feat: Add Publish confirmation modal [FC-0076] (#1677) 2025-03-11 17:37:40 -05:00
Muhammad Farhan
732fd28eb9 refactor: Improve conditions readability 2025-03-12 00:08:06 +05:00
Muhammad Farhan
091e120224 fix: Use defaultValue when item is null or empty 2025-03-12 00:08:06 +05:00
Brayan Ceron
1174b09ac4 fix: render proper visibility message on self-paced course type 2025-03-11 16:50:59 +05:00
Chris Chávez
b2472cfc0a refactor: Separate Publish order sort from publish filter [FC-0076] (#1701) 2025-03-10 10:55:15 -05:00
Rômulo Penido
17ebb90cd1 fix: paste button on unit page wasn't working (#1724) 2025-03-07 11:09:00 -08:00
Hina Khadim
49fbe766b0 fix: Prevent Alt Text from Being Truncated Due to Double Quotation Marks (#1721) 2025-03-07 23:17:37 +05:00
Rômulo Penido
dbba4dd296 fix: excessive calls to the clipboard API endpoint (#1700) 2025-03-07 08:16:39 -08:00
Chris Chávez
0eda5aec23 feat: Create advanced blocks in libraries [FC-0076] (#1653)
List view to show and create the advanced blocks
2025-03-05 12:46:17 -05:00
Dima Alipov
26c919a070 fix: default setting not updating with updated default settings 2025-03-04 17:01:39 +05:00
Demid
e9d85e85d3 fix: broken re-run notification dismiss (#1590) 2025-03-04 16:59:31 +05:00
Dmytro
e100193744 fix: prevent passing empty string in the date field to backend (#1457)
Co-authored-by: Dima Alipov <dimaalipov@192.168.1.101>
2025-03-04 16:59:00 +05:00
Peter Kulko
411607ec59 feat: [FC-0070] Manage Tags interoperation (#1454)
Added interaction between MFE and Legacy tagging functionality for xblocks on the Course unit page.
2025-03-03 11:07:04 -03:00
Rômulo Penido
06d591df13 fix: change ComponentPreview modal size to xl (#1650) 2025-02-26 17:27:51 -05:00
Jillian
e5360dc1f1 fix: allow users who can create orgs to see the full list of orgs when creating a course [FC-0076] (#1689)
The fixes for https://github.com/openedx/frontend-app-authoring/issues/1577 caused issues with edx.org's Global Staff users not being able to create courses. edx.org/2U Global Staff are seeing an empty Organization drop-down list.

This issue arose due to misuse of two similarly-named flags returned by the contentstore's home API

* `can_create_organizations`: granted to Global Staff or everyone if `FEATURES[ENABLE_CREATOR_GROUP] == True`, 
* `allow_to_create_new_org`: which is actually about auto-creating organizations, so both `can_create_organizations` + `settings.ORGANIZATIONS_AUTOCREATE` must be True

In this change, we use `canCreateOrganizations` to decide whether the user can see the full list of organizations when creating courses. We preserve the use of `allowToCreateNewOrg`  when deciding whether to allow users to "typeahead" to create a new organization not in the drop-down list.
2025-02-25 21:07:43 -05:00
Navin Karkera
11a7e78b73 fix: parsing text input problems (#1679)
* Parse incorrect answer fields in text input problems
* Fix feedback order
2025-02-25 15:41:49 -05:00
Rômulo Penido
56b7a7b17a feat: add component usage data in the ComponentDetails component [FC-0076] (#1656)
Adds the list of Courses and Units/Containers using a component to the "Details" tab on the sidebar.
2025-02-25 13:55:36 -05:00
Diana Olarte
6b2ba6e063 feat: cancellable block creation/edit workflow in libraries v2 (#1574)
Before, clicking "new problem" (etc) would create a new block, then launch the editor. Now it launches the editor and then creates the new block only on save. This makes the "Cancel" button work as expected. Only affects libraries so far, not courses.
2025-02-25 10:28:42 -08:00
Hina Khadim
63caf098a5 [TNL-11885] fix: resolve course-optimizer failure case bug (#1674)
* fix: resolve course-optimizer failure case bug

---------

Co-authored-by: Hina Khadim <hina.khadim@PF1H334R.2tor.net>
2025-02-25 14:52:16 +05:00
Kyle McCormick
8fe52d22e7 fix: Upgrade header, temporarily re-introducing Maintenance link (#1676)
We are temporarily re-introducing the Maintenance link, as the
Maintenance Announcements tool is still in use, as discussed on:
openedx/edx-platform#35852

There are no other significant changes in this version bump:
https://github.com/openedx/frontend-component-header/compare/v5.8.0...v5.8.3
2025-02-24 09:41:06 -05:00
Muhammad Faraz Maqsood
a0a0b9dc84 fix: Resolve Course Optimizer Scanning Bug
- Corrected LINK_CHECK_STATUSES.IN_PROGRESS value that is sent by backend.
2025-02-24 13:31:28 +05:00
Chris Chávez
ba896a3b15 feat: Enable transcripts for video library [FC-0076] (#1596)
* Get updateTranscriptHandlerUrl() and call it when is ready.
* Enable LanguageNamesWidget in a library.
* Enable add transcripts for libraries.
* Enable delete transcripts for libraries.
* Enable replace transcripts for libraries.
* Enable download transcripts for libraries.
* Enable download transcripts from YouTube
2025-02-21 13:33:50 -05:00
KEVYN SUAREZ
3e235d3360 fix: Adjust course import dropzone height to make course import status visible (#1664)
Closes: https://github.com/openedx/frontend-app-authoring/issues/1387
2025-02-21 16:48:57 +00:00
Chris Chávez
0db1727537 feat: Add cancel confirmation modal to Advanced editors in libraries [FC-0076] (#1672)
* Extracts the cancel confirmation modal as a new component.
* Adds the cancel confirmation modal to the Advanced editors in libraries.
2025-02-21 11:24:23 -05:00
Peter Kulko
7e4ecff4e8 feat: handle edit modals from advanced xblocks (#1445)
Adds new message types, updates message handlers, and implements a new modal iframe for legacy XBlock editing.
2025-02-20 17:05:48 -03:00
Saad Yousaf
2befd82e51 refactor: Update information message on Course Optimizer page 2025-02-20 16:57:17 +05:00
Navin Karkera
8275bbe8ce feat: course libraries page [FC-0076] (#1641)
Adds Libraries page that lists all library components being used in the current course to Content > Libraries
2025-02-18 10:36:31 -05:00
Chris Chávez
59243b0cb3 fix: Height in Advanced Editor [FC-0076] (#1649)
Updates the height of the Advanced Editor.
2025-02-13 11:22:02 -05:00
Braden MacDonald
0b08d82f03 fix: bugs with ExpandableTextArea toolbars & modals in problem editor (#1646)
* fix: clicking library name in Studio header would show 404

* fix: when ExpandableTextArea is in a modal, the selection toolbar could not be clicked

* fix: in ExpandableTextArea, shrink the "insert toolbar" that blocks the input

* chore: ignore coverage of modal fixer

* fix: make sure emoji/formula modals are working in the text editor too
2025-02-12 13:40:18 -08:00
Peter Kulko
e9130d3852 chore: iframe rendering optimization (#1544)
Iframe reload optimizations for various xblock related actions. Added some improvements related to scrolling to the current xblock. Fixed behavior of the xblock action dropdown list.
2025-02-11 16:31:07 -03:00
Chris Chávez
b0fc3d923b feat: Add drag and drop to LIBRARY_SUPPORTED_BLOCKS (#1651)
Add drag and drop v2 to LIBRARY_SUPPORTED_BLOCKS to enable the block by default
2025-02-07 12:47:33 -05:00
Daniel Valenzuela
05dddce920 feat: allow filtering library by publish status (#1570)
* Adds a filter widget for Publish status.
* Adds "Unpublished changes" badge.
2025-02-05 13:09:27 -05:00
Muhammad Farhan
31f39cb015 fix: regex mismatch in text block (#1597) 2025-01-30 09:13:26 -05:00
Braden MacDonald
b7241a124c docs: clarify/update a TODO comment about Meilisearch functionality (#1638)
Just a small update to a comment in the code, now that Meilisearch has new functionality that implements a feature we need.
2025-01-29 12:20:48 -05:00
Jillian
be600a91f0 feat: hide some settings fields when editing a library problem (#1601)
Hides some XBlock settings fields when editing library blocks. These hidden settings fields are relevant to course blocks, but not library blocks.

This change impacts Library Authors, and Course Authors who use Library Blocks and/or Problem Banks.
2025-01-27 10:47:09 -05:00
salman2013
de7affd97f chore: update catalog-info file and remove openedx.yaml file 2025-01-24 09:35:54 -05:00
Kristin Aoki
2102c7a612 fix: hidden remove button (#1600)
This PR fixes the visibility of the "Remove" button for grade segments. Previously, the button would appear on hover above the segment. But the styling of the button blocked it from being visible. Now, the button appears on hover under the grade range. This change impacts Course Authors.
2025-01-24 17:25:15 +05:00
Jillian
654c06b596 fix: a11y and performance issues with library authoring navigation [FC-0076] (#1593)
Fixes some a11y and performance issues for Library Authors

**Accessibility**

* When navigating between the various Library Authoring pages, the search keyword box should not be auto-focused, so focus will follow the user's click/tab events and keep that continuity.
The course content search modal behavior is unchanged -- loading this modal auto-focuses the search input box as one would expect.

**Performance**

* Navigating between the various Library Authoring pages was causing a full re-mount of the `<LibraryLayout/>` component
* React query's `staleTime` option is used to control how long data is considered fresh in both queries and routes. By default, the `staleTime` for queries is set to 0 milliseconds, meaning that the data will always be considered stale and will be refetched whenever the query is mounted.
2025-01-22 11:39:47 -05:00
Rômulo Penido
13b2ed5363 feat: add last published date to HistoryWidget [FC-0076] (#1585)
Adds the "Last Published" date to the `HistoryWidget`
2025-01-20 12:30:10 -05:00
Chris Chávez
fd6a6dd443 feat: Add AdvancedEditors with an iframe [FC-0076] (#1568)
Creates the AdvancedEditor to support editors like Drag and Drop, openresponse, poll, survey, and other advanced editors.

- AdvancedEditor created to call studio_view of the block
- Update LibraryBlock to support any view (and use studio_view in AdvancedEditor)
Intercept xblock-event message to close the Advanced editor on cancel or save
2025-01-16 13:22:27 -05:00
Ihor Romaniuk
619ab9a267 feat: [FC-0070] rendering library content in unit page (#1475)
The enables opening a Library Content page within the new Studio unit page. This page displays the xBlocks from the specified library and provides basic configuration options for the library.
2025-01-16 14:06:48 -03:00
Peter Kulko
98fbcff842 feat: [FC-0070] listen to xblock interaction events (#1431)
This is part of the effort to support the new embedded Studio Unit Page.  It includes changes to the CourseUnit component and the functionality of interaction between xblocks in the iframe and the react page.

The following events have been processed:

* delete event
* Manage Access event (opening and closing a modal window)
* edit event for new xblock React editors
* clipboard events
* duplicate event
2025-01-15 13:28:43 -05:00
Jillian
45f6ef42a7 fix: allow user provided value if can auto-create orgs [FC-0076] (#1582)
Allows Content Authors to auto-create an organization when creating a library, if auto-creating orgs is allowed by the platform.
2025-01-15 12:44:30 -05:00
Jesper Hodge
8385c4e8ed Feat course optimizer page (#1533)
Course Optimizer is a feature approved by the Openedx community that adds a "Course Optimizer" page to studio where users can run a scan of a course for broken links - links that point to pages that have a 404.

Depends on backend: openedx/edx-platform#35887 - test together.

This also requires adding a nav menu item to edx-platform legacy studio. That should be implemented before enabling the waffle flag on prod.

Links:
- [Internal JIRA ticket](https://2u-internal.atlassian.net/browse/TNL-11809)
- [Course Optimizer Discovery](https://2u-internal.atlassian.net/wiki/spaces/TNL/pages/1426587703/TNL-11744+Course+Optimizer+Discovery)
- [Openedx community proposal](https://github.com/openedx/platform-roadmap/issues/388)
2025-01-13 11:44:25 -05:00
Farhaan Bukhsh
e6bce560bc feat: Adding human readable 403 error access restricted (#1569)
Updated to have human-readable forbidden error (403)
2025-01-10 13:22:49 -05:00
Jillian
811be226d1 feat: shareable URLs for library components and searches [FC-0076] (#1575)
Adds new routes and URL parameters to use when viewing and performing searches on library components. These changes allow these pages to be bookmarked or shared by copy/pasting the browser's current URL.

No changes were made to the UI.

Use cases covered:

* As an author working with content libraries, I want to easily share any component in a library with other people on my team, by copying the URL from my browser and sending it to them.
* As an author working with content libraries, I want to easily share any search results with other people on my team, by copying the URL from my browser and sending it to them.
* As an author working with content libraries, I want to bookmark a search in my browser and return to it at any time, with the same filters and keywords applied.
* As an author of a content library with public read access, I want to easily share any component in a library with any authors on the same Open edX instance, by copying the URL from my browser and sending it to them.
* As an author of a content library, I want to easily share a library's "Manage Team" page with other people on my team by copying the URL from my browser and sending it to them.
* As an author working with content libraries, I want to easily share any selected sidebar tab with other people on my team, by copying the URL from my browser and sending it to them.
2025-01-10 10:36:46 -05:00
edX requirements bot
f586b095fa chore: update browserslist DB (#1494)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2025-01-06 10:38:02 -08:00
Rômulo Penido
dc0ba6aac4 fix: disable filter by block on collections tab [FC-0076] (#1576)
Adds the disabled prop for `FilterByBlockType` component and uses it on the Library Collection tab.
2024-12-21 07:01:22 -05:00
Rômulo Penido
230960b711 refactor: improve library sub header (#1573)
Changes the Library (and Collection) subheader
2024-12-18 12:56:21 -05:00
Chris Chávez
64906a1b9d refactor: Update error message while adding library team member [FC-0062] (#1572)
Update the error message while adding a library team member to show the error message generated by the server
2024-12-18 12:50:09 -05:00
Navin Karkera
b110b6bdc9 feat: undo component delete [FC-0076] (#1556)
Allows library authors to undo component deletion by displaying a toast message with an undo button for some duration after deletion.
2024-12-13 13:18:29 -05:00
Rômulo Penido
69bbeda816 refactor: split up library context (#1539)
Split the library context into smaller contexts:

* LibraryContext
* ComponentPickerContext
* SidebarContext
2024-12-12 13:14:45 -05:00
Brayan Cerón
c7e2bf9934 fix: find proper courses when searching (#1497)
When active/archived filters were on or there was selected any order filter, the search skipped these values and it was just returned the courses list without the respective filters. Additionally, when a search keyword was applied and a filter was selected, the keyword stayed stuck and the search list returned were not the appropriate
2024-12-09 14:44:02 -08:00
Daniel Valenzuela
73490a5741 fix: avoid changing url when removing filters (#1530)
* Makes the Active Tab Key independent from the URL, except for the initial load, where the active tab is set from the url.
*Avoids unnecessarily changing SearchParams: Due to a limitation of the useSearchParams react hook, which uses a memoized value for the URL that becomes stale after selecting a tab, it unexpectedly changes the URL value. Unfortunately there's no way to completely avoid this, so if there's a usageKey url param, the hook setter function will be called and the URL will revert to the stale memoized url.
2024-12-06 16:24:04 -05:00
Chris Chávez
d2d753203f fix: Update error messages when adding user to library [FC-0062] (#1543)
Updates the message error when the user doesn't exist when adding a new team member to a library.
2024-12-06 15:46:52 -05:00
Rômulo Penido
0e9025a670 fix: legacy library links were not working (#1548) 2024-12-06 18:50:53 +00:00
Rômulo Penido
2f1263ab5a fix: show/hide "new library" button based on separate v1/v2 permissions (#1545) 2024-12-06 10:40:45 -08:00
Chris Chávez
a0f6f4357e fix: Show published OLX in Library Content Picker [FC-0062] (#1534) 2024-12-05 14:13:04 -05:00
Braden MacDonald
e75ce15a67 refactor: Add TypeScript types for the Editors' Redux state (#1537)
It starts to add type information to the messy Redux state used by the editors, mostly focusing on the state shared by all editors and the problem editor.
2024-12-03 17:51:52 -05:00
Rômulo Penido
0771923183 feat: preserve library sidebar tab while switching items (#1535)
In the library home page, makes the selected tab on the sidebar persist while selecting Components or Collections Info Sidebar.
2024-12-03 17:13:22 -05:00
Braden MacDonald
6e53e37bfe refactor: Convert more Taxonomy code to TypeScript (2) (#1536)
* Converts some files from .js or .mjs to .ts
* Refactors some tests to use the new initializeMocks helper
* Cleans up and improves some type definitions
2024-12-02 09:24:17 -05:00
Braden MacDonald
abe68ac599 refactor: Convert more Taxonomy code to TypeScript (#1532)
* Converts some files from .js or .mjs to .ts
* Moves the API code from src/taxonomy/tag-list/data into src/taxonomy/data
* Cleans up and improves some type definitions
* No user-visible changes / functionality changes.
2024-11-27 15:31:55 -05:00
Rômulo Penido
f86c609ff1 fix: editor flicker after creating xblock (#1531) 2024-11-26 14:41:04 -08:00
Kyle McCormick
ec3f78f0ea feat!: remove Maintenance header link (#1526)
...by bumping frontend-component-header 5.7.0 -> 5.8.0

Our reasoning is that the two functions of the Studio Maintenance
dashboard (Announcements and Maintenance Banner) have been broken
for a while.

It's actually version 5.7.2 that removes the link [1] but since 5.8.0
has no breaking changes, it seemed prudent to jump straight to latest.

[1] https://github.com/openedx/frontend-component-header/releases/v5.7.2

Related PR: https://github.com/openedx/edx-platform/pull/35852
2024-11-26 09:49:34 -05:00
Navin Karkera
55fe87a3db feat: show problem bank component picker on window msg [FC-0062] (#1522)
Fix for: If you have a unit with many components and a problem bank on the NEW MFE unit page (with an iframe), clicking "Add Components" will open a modal that's way too tall.
2024-11-22 20:29:18 +00:00
Navin Karkera
7aa5accdbb feat: preview library block changes in course unit [FC-0062] (#1506)
Creates a new preview library block modal. Intercepts the message when the block is iframed to open the new modal.
2024-11-22 15:18:43 -05:00
Diana Olarte
31f59d6bca fix: Schedule and Details page was not loading (#1527)
The page relied on obscure behavior of setting "isLibrary" to disable image uploads even in a course context. This commit refactors to use an explicit enableImageUpload prop in TinyMceWidget.
2024-11-22 12:10:11 -08:00
Peter Kulko
bc8d59b0eb chore: [FC-0070] Some tests refactoring (#1518) 2024-11-21 15:24:31 -03:00
Ihor Romaniuk
b5419acd74 feat: [FC-0070] implement move xblock modal (#1422) 2024-11-21 15:22:41 -03:00
Braden MacDonald
66577b0d59 chore: bump frontend-build, remove exceptions for prefer-default-export (#1519) 2024-11-20 09:00:02 -08:00
Chris Chávez
624f5addcf fix: Show published count component in library content picker (#1481)
When using the library component picker, show the correct number on component count (published components) in collection cards.
2024-11-19 16:10:00 -05:00
Chris Chávez
0365e3809b fix: TinyMce aux modal issues in text editors [FC-0062] (#1500)
The following bugs were found with the TinyMCE aux modal (used in emoticons, formulas and embed iframe):

* The TinyMCE aux modal and the Editor modal close when clicking on any content in the aux modal.
* When the user opens the Edit Source Code modal, this adds data-focus-on-hidden to the TinyMce aux modal, making it unusable (not clickable).
* Since they are two separate modals, the focus remains on the editor modal, making it impossible to use scrolling or inputs from the modal aux.

Solution: Move the aux modal inside the editor modal.

One discarded solution: Block the modal editor from closing when interacting with the modal aux. The modal editor still retained focus.
2024-11-19 15:10:04 -05:00
Diana Olarte
b260708080 test: fix contentContainer test (#1516) 2024-11-19 12:24:32 -05:00
Diana Olarte
f740f57454 feat: upload images to v2 library components from the TinyMCE in library editor (#1458) 2024-11-18 10:38:08 -08:00
Peter Kulko
ba48a273a1 fix: fixed Configure modal for unit page (#1452) 2024-11-18 11:39:44 -03:00
Peter Kulko
0706a09acb fix: error handling (#1079)
Added alert message if 403 error occurs.
2024-11-18 11:27:36 -03:00
Régis Behmo
771c5d3e19 docs: minor README improvements (#1504) 2024-11-15 10:32:22 -08:00
Kyle McCormick
6ffdb01c24 refactor: remove pointless maintenance link message (#1503)
This link is defined in frontend-component-header, so the message
shouldn't be here. Anyway, we are deleting the link from
frontend-component-header too

Related:
* https://github.com/openedx/frontend-component-header/pull/553
* https://github.com/openedx/edx-platform/pull/35852
2024-11-15 10:55:23 -05:00
Pooja Kulkarni
32e5fa68d8 fix: Adjust styling when title is truncated (#1382) 2024-11-14 17:30:19 -05:00
Navin Karkera
cee88885d9 feat: enable problem bank button functionality on unit page (#1480) 2024-11-14 12:00:23 -08:00
Navin Karkera
033acc45f1 fix: remove unnecessary toast notification on adding component (#1490)
Fix for: #1489
2024-11-14 12:03:09 -05:00
Navin Karkera
efd2b3d27d feat: show info banner in component picker (#1498)
Displays a infor banner if only published content is visible in component picker.
2024-11-13 13:54:20 -05:00
Peter Kulko
9b4cf8718f fix: fixing broken tests 2024-11-11 11:20:15 -03:00
Rômulo Penido
67faf9a63a fix: infinite scroll bug on library page (#1483) 2024-11-08 10:59:48 -08:00
Peter Kulko
e59f2846e3 feat: render iframe with xblocks (#1375)
This refactors the CourseUnit component by removing the DraggableList and CourseXBlock components and replacing them with a simpler XBlockContainerIframe. Additionally, it introduces new constants for iframe handling.
2024-11-08 10:53:32 -03:00
Peter Kulko
f9ef00e29f feat: [FC-0070] Remove backend redirects (use SPA functionality) (#1372)
Introduces the ability to utilize SPA functionality when the relevant waffle flags are enabled for current MFE pages. When any new MFE page is loaded, a request is made to retrieve the waffle flags. This includes both global waffle flags related to MFE Authoring pages, as well as waffle flags specific to the current course.
2024-11-08 08:19:23 -03:00
Daniel Valenzuela
979c69b48e feat: simplify Library Home Page (v2) (#1443) 2024-11-07 09:48:19 -08:00
Rômulo Penido
d99e3f0f62 fix: add spacing to searchbar and simplify render conditions (#1461)
Adds padding between the search bar and the library list.

Also, the render method was refactored to be a bit simpler.
2024-11-06 22:01:38 -05:00
Jillian
f1bdc6200f fix: show a more detailed error on Bad Request (#1468)
Show a detailed error when 400 Bad Request received while adding a component to a library, either a new or pasted component. The most likely error from the backend here is "library can only have {max} components", and since this error is translated already, we can just report it through.
2024-11-06 21:53:24 -05:00
Navin Karkera
e118eb5971 chore: hide transcripts in video preview for library (#1459)
Fixes: #1453
2024-11-05 15:15:28 -05:00
Jillian
d7bbd40de1 fix: Hide / error on Libraries v2 pages if !librariesV2Enabled (#1449)
Show an error message if the user tries to view a v2 Library while Libraries V2 are disabled in the platform.
2024-11-05 15:14:09 -05:00
edX requirements bot
fc94667a57 chore: update browserslist DB (#1381)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2024-11-04 12:27:02 -08:00
Navin Karkera
df8a65dc4e feat: handle unsaved changes in text & problem editors (#1444)
The text & problem xblock editors will display a confirmation box before
cancelling only if user has changed something else it will directly go
back.
2024-11-04 12:41:00 -05:00
Rômulo Penido
949e4ac94c fix: enable publish button on library after component edit [FC-0062] (#1446)
Fixes the following bug: After publishing a library then editing a component, the "Publish" button in Library Info doesn't become enabled until you refresh. Updates the apiHooks to invalidates library query.
2024-11-01 13:58:39 -05:00
Navin Karkera
549dbaa0fa fix: add component to collection on paste [FC-0062] (#1450)
Link component to collection if pasted in a collection page.
Fixes: https://github.com/openedx/frontend-app-authoring/issues/1435
2024-10-31 17:44:34 -05:00
Bilal Qamar
28569aa3da test: Remove support for Node 18 (#1247)
* test: Remove support for Node 18

* chore: update code coverage artifact naming
2024-10-31 15:32:54 -04:00
Rômulo Penido
ecfe27b043 fix: empty state for library selection on component picker [FC-0062] (#1440)
This PR fixes the empty state text for adding library content if the user can't access any library.
2024-10-28 18:49:18 -05:00
Chris Chávez
cff1177ae9 fix: Library Preview Expand button covers dropdown (#1438) 2024-10-25 13:55:24 -07:00
Kshitij Sobti
4d4adce715 feat: Use configured DEFAULT_GRADE_DESIGNATIONS (#1227)
Support was recently added to edx-platform to add customisised default grade
designations, this change adds support for them to this MFE as well to bring it
to partiy with the edx-platform UI

It also refactors the grading-settings page to use React Query and updates the
logic used when partitioning grades by default to make it work better when there
are more than 5 partitions.

Co-authored-by: Farhaan Bukhsh <farhaan@opencraft.com>
2024-10-25 15:34:04 +05:30
Jillian
774728a9c0 fix: use absolute URL for Export Tags menu item (#1432)
use absolute URL for Export Tags menu item so that the menu item works no matter where in the course it's used. Fix this issue: https://github.com/openedx/frontend-app-authoring/issues/1380
2024-10-24 21:03:51 -05:00
Braden MacDonald
3d8d248599 feat: arbitrary asset upload/deletion for Library Components [FC-0062] (#1430)
Allow users to upload and delete assets associated with Content Library
components via the sidebar panel, under the "Advanced Details" section
of the "Details" tab. This is intended as a debug tool and power-user
feature, similar to the OLX editor provided there. It's also serving as
our interim image-upload solution, because it was easier to implement
than the full modal that integrates with TinyMCE.

---------

Co-authored-by: XnpioChV <xnpiochv@gmail.com>
2024-10-24 09:46:27 -04:00
Cristhian Garcia
e1ce3eb484 fix: display image preview in libraries editor (#1403)
Prior to this commit, the TinyMCE editor image preview only worked in
courses, and did not work for content libraries.
2024-10-24 09:39:37 -04:00
Rômulo Penido
a8aa495542 feat: add existing content to a collection [FC-0062] (#1416)
Allows library components to be added to a collection using the add-content
sidebar. For the Libraries Relaunch Beta.

For: https://github.com/openedx/frontend-app-authoring/issues/1173
2024-10-23 11:49:46 -04:00
Navin Karkera
c0c74dec83 feat: show confirmation dialog before discarding library changes [FC-0062] (#1428)
* feat: show confirmation dialog before discarding library changes
2024-10-23 10:47:23 -05:00
Navin Karkera
f67c3ffc4c feat: direct link to single block in library [FC-0062] (#1392)
* feat: direct link to single block in library

Adds support for displaying single xblock in a library when passed a
query param: usageKey. This is required for directing users to a
specific block from course.

* feat: show alert while editing library block from course
2024-10-23 10:25:54 -05:00
Rômulo Penido
11470f256d feat: library component picker now supports multi-select (#1417) 2024-10-22 16:41:49 -07:00
Brian Smith
fe37d119f2 feat(deps): update header to 5.6.0 (#1424) 2024-10-22 19:18:50 -04:00
Braden MacDonald
8c8d9119d4 fix: don't revert to advanced editor if problem contains fields like url_name (#1421) 2024-10-22 18:53:22 +00:00
Chris Chávez
21cbf80f23 feat: Show published components on content picker (#1420)
* feat: Show published components on content picker

---------

Co-authored-by: Braden MacDonald <braden@opencraft.com>
2024-10-22 13:47:07 -05:00
Daniel Valenzuela
966e1c3d91 feat: publish single library component (#1407) 2024-10-22 17:31:17 +00:00
Braden MacDonald
57e7baf59e fix: this repo has been renamed to frontend-app-authoring (#1419) 2024-10-22 10:19:24 -07:00
Navin Karkera
675e02fcbd feat: "add to collection" menu item functionality (#1413) 2024-10-22 09:49:51 -07:00
Braden MacDonald
841aede8cd perf: don't load advanced info details (library components) before they're needed (#1409) 2024-10-21 14:07:28 -07:00
Braden MacDonald
6ae68bd122 feat: Menu option to delete a component + small fixes (#1408)
* feat: menu option to delete a component
* feat: close component sidebar if it's open when that component id deleted
* feat: hide unsupported block types from the "Add Content" menu
* fix: expand and internationalize the "component usage" text
2024-10-21 14:04:45 -07:00
Navin Karkera
d49fc85163 refactor: remove parentLocator and next button from lib component picker (#1412) 2024-10-21 10:05:04 -07:00
Navin Karkera
56e025a4f0 refactor: lib component picker modal to only post message with block info (#1401) 2024-10-19 11:55:25 -07:00
Max Sokolski
a94df2fdf0 fix: set original value for TypeaheadDropdown component 2024-10-18 16:35:53 -03:00
Jillian
cfe19894d1 feat: Let Studio Home REST API determine if libraries v1 and/or v2 are enabled (#1329) 2024-10-18 12:03:26 -07:00
Braden MacDonald
40a6ee9ca5 feat: View for comparing published version of library block to previous (#1393) 2024-10-18 11:27:10 -07:00
Chris Chávez
4facf1cf5d feat: add tags to collections [FC-0062] (#1379)
* feat: Add ContentTagsDrawer to collection

* test: Add test to show ContentTagsDrawer on CollectionInfo
2024-10-16 21:50:17 -05:00
Rômulo Penido
b81f611a0e feat: add library component picker (#1356) 2024-10-16 10:18:12 -07:00
Maria Grimaldi
8a4d1f4810 refactor!: turn on homepage course API V2 consumption by default (#1307)
* refactor!: turn on homepage course API V2 consumption by default

Turn on getting courses from the HomePageCourses API
which allows pagination, filtering and ordering. See https://github.com/openedx/edx-platform/pull/34173
for more details on the API implementation.

* fix: home page initial a-z course sort

---------

Co-authored-by: Diana Olarte <diana.olarte@edunext.co>
2024-10-16 12:29:20 -04:00
David Ormsbee
1bdea093b0 fix: disable static asset mangling for v2 Content Libraries
The static asset substitution used to make images show up properly when
in the TinyMCE editor doesn't work for Content Libraries. Unfortunately,
this will cause the static asset references in XBlock content to get
mangled and saved incorrectly. So until we can handle it correctly,
we're just going to disable it entirely if the LearningContext is a v2
Content Library.

This means that static assets won't display properly in the editor
itself, but it should at least get written/preserved correctly, so that
those assets will show up properly in XBlock previews.
2024-10-16 11:54:19 -04:00
David Ormsbee
a1181f3d49 refactor: switch Content Library XBlock preview to Studio
edx-platform commit 7316111 (PR #35598) moved the XBlock embed view so
that it can be rendered on either LMS or Studio. This commit moves the
frontend to actually call the Studio endpoint. This will make Content
Library static asset display easier, because that view will only be made
available through Studio and not the LMS.
2024-10-16 11:54:19 -04:00
Stanislav
ba8e3d448e fix: Calendar icon over datepicker modal (#1365) 2024-10-16 10:20:27 -04:00
Jillian
1ee3229104 feat: UI to manage users/permissions for the content libraries (#1362) 2024-10-15 17:24:00 +00:00
Navin Karkera
84487602cc feat: manage collections in component sidebar [FC-0062] (#1373)
* feat: add to collection in sidebar

* feat: manage collections

* test: add tests for manage collections

* feat: remove from collection menu option
2024-10-15 10:20:23 -05:00
Navin Karkera
7fb460019e feat: add an allowlist of for supported blocks in library [FC-0062] (#1378)
* feat: show error msg from server on paste

* feat: add an allowlist of for supported blocks in library

Libraries v2 currently don't support editing blocks other than problem,
text and videos. This commit adds a configuration variable called
`LIBRARY_SUPPORTED_BLOCKS` to setup allowed list of block types users
can paste into libraries. By default it is set to support
'problem,text,video,html`.

* feat: enable add button for blocks based on setting


---------

Co-authored-by: Rômulo Penido <romulo@opencraft.com>
2024-10-15 09:52:35 -05:00
Braden MacDonald
66b14a5b16 docs: update the README with an easy way to run the MFE on your host (#1364) 2024-10-10 14:02:42 -07:00
ABBOUD Moncef
3696836de6 feat: save discussion alert dismissal (#1245) 2024-10-09 16:23:12 -04:00
Navin Karkera
434fea3a95 feat: delete collection [FC-0062] (#1333)
* feat: delete collection

* feat: update button status on delete

* test: add tests for collection delete
2024-10-08 16:59:06 +00:00
Braden MacDonald
75f937e11a feat: Libraries v2: Advanced Component Info & OLX Editor (#1346) 2024-10-08 09:41:21 -07:00
Rômulo Penido
85b5730114 fix: change collection details component slots (#1363) 2024-10-07 21:34:48 -05:00
Braden MacDonald
8c125df9aa feat: Open Editors in a Modal (library components only) [FC-0062] (#1357)
* feat: allow opening editors in modals

* refactor: add an EditorContext

* test: update tests accordingly

* test: make testUtils call clearAllMocks() automatically :)
2024-10-07 21:04:49 -05:00
edX requirements bot
83322e2052 chore: update browserslist DB (#1367)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2024-10-07 10:15:40 -07:00
dependabot[bot]
b6eeec8e60 build(deps): bump actions/checkout from 3 to 4 (#1371) 2024-10-07 10:12:16 -07:00
Jillian
b957f3b4e3 Use block type label instead of Library block_types REST API [FC-0062] (#1361)
* style: avoid using reserved word "type" as variable name

use componentType or blockType instead.

* refactor: let BlockTypeLabel handle displaying the component label

including the child count, if one is provided.

This change removes hooks for the block_types REST API

* test: add tests for BlockTypeLabel

---------

Co-authored-by: Chris Chávez <xnpiochv@gmail.com>
2024-10-04 13:04:23 -05:00
Jillian
9c1fd5a68c fix: Show spinner while loading library components (#1331) 2024-10-03 21:02:32 -07:00
Braden MacDonald
652af9f6a5 refactor: Improve LibraryContext, convert tests to testUtils (#1345) 2024-10-03 19:35:43 -07:00
Jillian
dc6ede4d80 fix: use "other" component type in decide Card header background (#1359)
if no other background color is found
2024-10-03 15:26:12 -07:00
Jesper Hodge
8c6bbb895f fix: update express (#1351)
Just a package update
2024-10-03 15:21:37 -04:00
Braden MacDonald
4d0f92e265 fix: upload codecov report as a separate workflow step (#1355) 2024-10-02 10:49:38 -07:00
Rômulo Penido
0349188c42 feat: allow full width content in library authoring [FC-0062] (#1258)
* feat: allow full width content in library authoring

* chore: update header and footer versions

---------

Co-authored-by: Jillian <jill@opencraft.com>
2024-10-02 06:16:25 -05:00
Rômulo Penido
b1772383f4 fix: component preview modal overflow (#1348) 2024-10-01 16:56:58 -07:00
Kristin Aoki
b71f2148c9 feat: update ora settings to only be flexible peer grading (#1332) 2024-10-01 13:11:52 -04:00
edX requirements bot
e9c10c7f9e chore: update browserslist DB (#1347)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2024-09-29 17:35:01 -07:00
Rômulo Penido
4d67e8bda9 feat: improve collection sidebar (#1320)
* feat: improve collection sidebar

* feat: add comments to splice blockTypesArray code

Co-authored-by: Jillian <jill@opencraft.com>
---------

Co-authored-by: Jillian <jill@opencraft.com>
Co-authored-by: Chris Chávez <xnpiochv@gmail.com>
2024-09-27 21:24:12 -05:00
Dmytro
c80483c053 fix: Create button remains deactivated until pick a new org (#1279)
Co-authored-by: Dima Alipov <dimaalipov@192.168.1.101>
2024-09-27 11:37:32 -04:00
Chris Chávez
2cd77ce455 feat: Add tags to manage sidebar of library components (#1299) 2024-09-26 23:33:36 -07:00
Braden MacDonald
95c17537c1 fix: don't revert to advanced problem editor when max_attempts is set (#1326) 2024-09-26 09:50:28 -07:00
Braden MacDonald
3662fadad4 feat!: Remove support for the (deprecated) library authoring MFE (#1327) 2024-09-26 08:38:16 -07:00
Braden MacDonald
ccce44a1c8 fix: library metadata times are actually displayed in local time (#1309) 2024-09-25 17:26:36 -07:00
Rômulo Penido
ff67c9a952 feat: add component Details sidebar [FC-0062] (#1303)
* feat: add ComponentDetails component

---------

Co-authored-by: Jillian <jill@opencraft.com>
2024-09-25 14:33:45 -05:00
renovate[bot]
c13ab00344 chore(deps): update dependency @openedx/frontend-build to v14.1.4 (#1308)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-25 10:17:08 -07:00
Rômulo Penido
b6ec5e1e3a fix: remove preview overlay from library component sidebar (#1323) 2024-09-25 09:32:49 -07:00
Braden MacDonald
5f41db83c2 feat: Enable the Video editor in content libraries [FC-0062] (#1319)
* feat: enable video editor in libraries

* fix: a11y issue in video editor - URL and ID fields were combined

* test: tests for video editor
2024-09-24 21:11:06 -05:00
Braden MacDonald
95521d3b8d Cleanups for the video editor [FC-0062] (#1318)
* refactor: cleanups to video editor code

* test: ignore coverage of blank default data
2024-09-24 20:55:15 -05:00
Braden MacDonald
64d718d198 fix: Use soft nav when clicking a library from studio home (#1306) 2024-09-24 09:32:56 -07:00
edX requirements bot
353ef508df chore: update browserslist DB (#1312)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2024-09-23 13:22:37 -07:00
renovate[bot]
8b50449c1f fix(deps): update dependency npm to v10.8.3 (#1313)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-23 09:38:30 -07:00
Navin Karkera
b7ae82bde2 feat: Collections page (in libraries) (#1281) 2024-09-20 10:15:25 -07:00
renovate[bot]
0d472ae66f chore(deps): update dependency eslint-import-resolver-webpack to v0.13.9 (#1284)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-19 13:52:05 -07:00
Zachary Hancock
4e609e02e5 feat: improve error message for proctored exam settings (#1300) 2024-09-19 16:03:34 -04:00
Braden MacDonald
8d49f2ed4e feat: display library title in browser tab (#1305) 2024-09-19 12:34:48 -07:00
Stanislav
f3274e70a6 fix: Fix content overflow in the Pages & Resources modal windows (#1301) 2024-09-19 15:16:53 -04:00
Navin Karkera
9d3a05f1bd feat: show children count in collection card (#1298) 2024-09-19 09:50:38 -07:00
Chris Chávez
053a9b1074 fix: inconsistency with the select all functionality in problem capa type filter (#1294) 2024-09-18 11:35:56 -07:00
Rômulo Penido
fc4b700624 fix: responsiveness on library authoring sidebar (#1293)
* fix: responsiveness on library authoring sidebar

* fix: adjust margin to prevent height change

* fix: prevent button stretch
2024-09-18 11:19:56 -07:00
Braden MacDonald
314dfa60e2 feat: Enable capa problem editor for components in libraries (#1290)
* feat: enable the problem editor for library components

* fix: don't try to load "advanced settings" when editing problem in library

* fix: don't fetch images when editing problem in library

* docs: add a note about plans for the editor modal

* fix: choosing a problem type then cancelling resulted in an error

* chore: remove unused mockApi, clean up problematic 'module' self import

* test: update workflow test to test problem editor

* feat: show capa content summary on cards in library search results

* docs: fix comment typos found in code review

* refactor: add 'key-utils' to consolidate opaque key logic
2024-09-18 17:45:41 +00:00
Braden MacDonald
b01090902a fix: propTypes warnings in Problem Editor, refactor some code to TS (#1280)
* fix: a11y - missing 'alt' text for Problem Editor IconButton
* fix: warning in <ProblemTypeSelect> component - missing key prop in list
* fix: warning: `problemType` required in `ProblemEditor`, but is `null`
* fix: warning: The prop `onClose` marked as required in `SelectTypeModal`
* fix: warning: prop `name` is marked as required in `ForwardRef(_c)`
* fix: warning: props `alt`, `id`, and `key` are required
* test: improve test coverage of SelectTypeModal, refactor some code
* test: improve test coverage
2024-09-18 17:01:56 +00:00
Stanislav
82a3b7c986 fix: Fix content overflow in the Overwrite Files modal window (#1291) 2024-09-17 10:28:18 -04:00
renovate[bot]
fb3533ad49 fix(deps): update dependency frontend-components-tinymce-advanced-plugins to v1.0.4 (#1285)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-16 19:34:58 +00:00
Rômulo Penido
dd7e4d4297 feat: add component sidebar manage tab [FC-0062] (#1275) 2024-09-16 14:13:41 -05:00
Kristin Aoki
902853d649 fix: isInitialized selector depends on unitUrl for course blocks (#1288) 2024-09-16 14:34:56 -04:00
Kyle McCormick
6eed6438cb docs: update README based on rename (#1289) 2024-09-16 13:05:12 -04:00
edX requirements bot
644f1706a2 chore: update browserslist DB (#1283)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2024-09-16 09:49:11 -07:00
Brayan Cerón
80e3592669 refactor: remove thumbnail for non-edX videos & allow removing fallback URLs (#1241)
* refactor: remove thumbnail from non-edx videos

* fix: when deleting a fallback URL the app crashed

* refactor: simplify conditional rendering
2024-09-16 11:53:05 -04:00
Rômulo Penido
121ced42ec feat: preview components (xblocks) on library authoring pages (#1242) 2024-09-14 10:03:49 -07:00
Chris Chávez
a37a1b1ef8 feat: Create collection Modal [FC-0062] (#1259)
* feat: Enable Collection button on Create Component in Library

* feat: CreateCollectionModal added

* test: For CreateCollectionModal

* refactor: Migrate FormikControl to TypeScript

* test: Add tests for EmptyStates
2024-09-13 21:07:02 -05:00
Braden MacDonald
fd48fef299 feat: edit Text components within content libraries [FC-0062] (#1240) 2024-09-12 19:39:42 -07:00
Navin Karkera
9b61037311 feat: collections tab [FC-0062] (#1257)
* feat: add collections query to search results

* feat: collections tab with basic cards

* feat: add collection card also fix inifinite scroll for collections

* feat: collection empty states

* test: add test for collections card
2024-09-12 18:55:34 -05:00
renovate[bot]
4035931cbb fix(deps): update dependency @openedx/paragon to v22.8.1 (#1268)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-12 19:26:42 +00:00
renovate[bot]
e2e3104474 fix(deps): update dependency @edx/frontend-component-footer to v14.0.10 (#1244)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-12 19:25:27 +00:00
edX requirements bot
88a038c0ea chore: enable github action auto update in dependabot.yml (#1256) 2024-09-12 15:12:17 -04:00
Demid
45c68d6ca4 Hide "Advanced Settings" settings item [BB-9081] (#1252)
* refactor: convert header utils to hooks

* feat: hide advanced settings button if a user doesn't have access
2024-09-12 14:55:01 -04:00
Dmytro
56728310f4 fix: create course button inactive after using org drop-down (#1276)
Co-authored-by: Dima Alipov <dimaalipov@192.168.1.101>
2024-09-12 12:46:04 -04:00
renovate[bot]
9bbbf610b7 fix(deps): update dependency @edx/openedx-atlas to v0.6.2 (#1228) 2024-09-11 11:30:51 -07:00
Braden MacDonald
6255768c97 test: refactor and fix flakiness of LibraryAuthoringTest (#1263) 2024-09-10 13:34:22 -07:00
Dmytro
513309c160 fix: no validation for combined length of org, number, run (#1262)
Co-authored-by: Dima Alipov <dimaalipov@192.168.1.101>
2024-09-10 10:24:11 -04:00
edX requirements bot
bbe15afbe9 chore: update browserslist DB (#1175)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2024-09-09 14:41:08 -07:00
Braden MacDonald
f9c11f8129 feat: Add type stubs for frontend-platform/i18n (#1251) 2024-09-09 09:30:14 -07:00
Braden MacDonald
376f31ebae chore: clean up dependencies (#1255) 2024-09-09 09:27:15 -07:00
renovate[bot]
849471bfed chore(deps): update dependency @openedx/frontend-build to v14.1.2 (#1213) 2024-09-06 13:27:43 -07:00
Kaustav Banerjee
6b10fa7401 feat: remove new library button if user does not have create access for v1 libraries (#1216) 2024-09-06 10:49:38 -07:00
Kyr
3a61e84c50 feat: fixed height for prerequisite course dropdown list (#1154)
Co-authored-by: Kyrylo Hudym-Levkovych <kyr.hudym@kyrs-MacBook-Pro.local>
2024-09-06 10:28:55 -04:00
Kristin Aoki
dcf05cde07 fix: tinymce render outside of editors (#1254) 2024-09-05 13:18:26 -07:00
Chris Chávez
34f0bf5253 fix: UX nits on Library Info Sidebar (#1253) 2024-09-04 10:25:36 -07:00
Rômulo Penido
c4d00017e0 fix: FilterItem key warning (#1246) 2024-09-04 08:51:13 -05:00
Braden MacDonald
735d978894 refactor: Merge frontend-lib-content-components into this repository 2024-08-29 10:19:17 -07:00
Braden MacDonald
9d0898cdfe chore: update with master 2024-08-29 10:03:55 -07:00
Bilal Qamar
1e7e3e7036 build: Upgrade to Node 20 (#1209)
* feat: updated node to v20

* refactor: updated package-lock along with ci & lockfile version workflows

* refactor: updated lockfile version workflow
2024-08-29 12:08:30 -04:00
Rômulo Penido
48e0ec1f70 feat: add library component sidebar [FC-0062] (#1217) 2024-08-29 07:22:13 -05:00
Braden MacDonald
af2b4dd3cb fix: remove another accidental import of test code from the build 2024-08-28 10:51:36 -07:00
Chris Chávez
64ffaddf3c feat: Capa problem types submenu [FC-0059] (#1207) 2024-08-28 08:16:02 -05:00
Braden MacDonald
7d7394521b chore: update with latest master 2024-08-27 13:45:23 -07:00
Ihor Romaniuk
f36b2183d6 fix: reset active answers for single answer problem type (#426) 2024-08-27 13:44:11 -07:00
Braden MacDonald
83fda560c1 fix: remove accidental import of test code from the build 2024-08-27 13:41:55 -07:00
Chris Chávez
d99a09efba fix: Library v2 info sidebar UI fixes (#1226) 2024-08-26 13:33:54 -07:00
Jillian
259a50c468 UI fixes for Sort Library Component [FC-0059] (#1222)
fix: use "Recently Modified" as the default sort option

When search keyword(s) are entered, use "Most Relevant" as default.

Also

* Hides "Most Relevant" option if no keyword is entered.
* Re-orders the sort menu options
* Ensures the default sort option is not stored in the query string
* Shows the selected sort option on the drop-down toggle button
* Shows "Sort By" as a header inside the drop-down menu
2024-08-23 19:11:53 -05:00
Bilal Qamar
3e0f7b5758 test: Add Node 20 to CI matrix (#1224) 2024-08-22 14:37:36 -04:00
Rômulo Penido
21c9e30207 refactor: change toast component (#1211) 2024-08-22 08:50:43 -05:00
Muhammad Anas
8ae9dfbd88 feat: customize the certificate link in header (#1223)
* feat: customize the certificate link in header

* fix: lint issues

* fix: tests
2024-08-21 10:36:14 -04:00
Navin Karkera
3089d0b993 fix: discard button [FC-0062] (#1214)
* fix: discard changes

* refactor: disable discard btn for new libs

Enable it if components are added.

* refactor: invalidate library related content queries

* chore: add comment about content search query invalidation
2024-08-20 21:12:06 -05:00
renovate[bot]
47cec6e4c9 fix(deps): update dependency @edx/frontend-lib-content-components to v2.6.8 (#1218)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-20 15:21:54 -04:00
Rômulo Penido
f370b565c2 fix: dropdown checkbox click area (#1215) 2024-08-17 16:43:27 -07:00
Braden MacDonald
155a710aa8 chore: work around type error with <SelectableBox> 2024-08-17 16:41:12 -07:00
Braden MacDonald
591a02e8a7 chore: update with master 2024-08-17 16:27:00 -07:00
Braden MacDonald
f90bbb2de7 chore: update to frontend-lib-content-components 2.6.8 2024-08-17 16:23:19 -07:00
Braden MacDonald
28e1956708 chore: update imports, fix lint issues 2024-08-17 16:12:58 -07:00
Ihor Romaniuk
b55e5c9f8f fix: answer range validation in Numerical input (#482) 2024-08-16 12:19:11 -04:00
Kyr
a9e8bd5558 fix: license widget checkbox and link (#486)
* fix: share alike after save, license link for creative common

* test: update snapshot

---------

Co-authored-by: Kyrylo Hudym-Levkovych <kyr.hudym@kyrs-MacBook-Pro.local>
2024-08-16 10:19:13 -04:00
Yusuf Musleh
95ac0983a3 feat: Add "Paste from Clipboard" to lib v2 sidebar (#1187) 2024-08-15 10:03:39 -07:00
renovate[bot]
7c59b4a210 fix(deps): update dependency @openedx/paragon to v22.7.0 (#1180)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-13 16:39:37 -04:00
renovate[bot]
de3befec08 fix(deps): update dependency @edx/frontend-component-header to v5.3.4 (#1179)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-13 18:08:37 +00:00
renovate[bot]
6ff3847c6c fix(deps): update dependency @edx/openedx-atlas to v0.6.1 (#1123)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-13 13:53:33 -04:00
renovate[bot]
ea90e7e93c fix(deps): update dependency @edx/frontend-lib-content-components to v2.6.6 (#1210)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-13 17:50:42 +00:00
renovate[bot]
48ffa0f970 fix(deps): update dependency @edx/frontend-component-footer to v14.0.8 (#1161)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-13 17:49:42 +00:00
Chris Chávez
4f5346ed31 feat: Library info sidebar - allows lib rename+publish (#1138) 2024-08-13 10:37:34 -07:00
Ihor Romaniuk
940482dd9a fix: add validation to problem number fields (#425) 2024-08-12 11:04:28 -04:00
renovate[bot]
8285f8ec5a fix(deps): update dependency @edx/frontend-lib-content-components to v2.6.5 (#1206)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-12 09:43:34 -04:00
Braden MacDonald
afa2317131 feat: 'frontend-lib-content-components' into this repo 2024-08-09 11:48:49 -07:00
Braden MacDonald
d3d5fe0e1b Removed unneeded files from lib-content-components 2024-08-09 11:47:35 -07:00
Kristin Aoki
b088a8fe3d fix: asset name parsing in static converter (#501) 2024-08-09 13:02:34 -04:00
Rômulo Penido
bb88101255 feat: add "copy to clipboard" feature to library authoring UI (#1197) 2024-08-08 09:32:04 -07:00
Chris Chávez
a7645afd22 fix: UI fixes for read-only libraries etc. (#1198)
* fix: Hide open Create content buttons without permissions

* feat: Read only badge on library Home

* refactor: library authoring to get canEditLibrary from useContentLibrary

* style: Typo on the code
2024-08-07 18:26:32 -07:00
Kristin Aoki
7379e734a0 feat: replace progress bar with loading spinner (#1192) 2024-08-07 12:07:22 -04:00
Kristin Aoki
3d82d37943 Revert "fix(deps): update dependency @edx/frontend-lib-content-components to …" (#1205)
This reverts commit 6f13164998.
2024-08-06 12:50:21 -04:00
Brandon Bodine
553acd8fcc chore: remove unused ai-translations env vars (#1204) 2024-08-06 07:17:08 -06:00
renovate[bot]
6f13164998 fix(deps): update dependency @edx/frontend-lib-content-components to v2.6.4 (#1184)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-05 09:31:12 -04:00
Jorg Are
9efb583cdc feat: replace ai-translations component with a plugin slot (#1186)
* feat: replace ai-translations component with a plugin slot

* feat: move ai-translations enabled check to plugin
2024-08-05 13:46:50 +01:00
Kristin Aoki
b68257e176 fix: remove imports breaking build (#500) 2024-08-02 15:04:49 -04:00
Rômulo Penido
680b5ff160 refactor: convert a couple files to TS and improve typings/tests (#1181)
* refactor: convert files to ts and improve typings/tests

* fix: set return type to unkown for future fix
2024-08-02 09:26:10 -07:00
Kristin Aoki
beb4813c53 fix: setAssetToStaticUrl regex matcher (#497) 2024-08-01 15:56:32 -04:00
Ihor Romaniuk
ce8703799b fix: add rtl support to editor (#424) 2024-08-01 13:21:01 -04:00
Adolfo R. Brandes
5825dd36d3 Merge pull request #487 from open-craft/braden/fix-extra-scss
fix: don't accidentally bundle paragon CSS x2
2024-08-01 09:55:35 -03:00
Jillian
cba85ab96d test: fix flaky library-authoring test (#1193) 2024-07-30 13:33:24 -07:00
Kristin Aoki
cc3bbfd9af fix: package.json out of sync with package-lock.json and upgrade (#1194) 2024-07-30 20:24:37 +00:00
Jillian
4f88948844 feat: adds sort widget to search manager and library component page (#1147) 2024-07-30 09:41:10 -07:00
Yusuf Musleh
699cbeadb3 feat: Add cancel create library button (#1182) 2024-07-26 09:39:24 -07:00
Rômulo Penido
6382898213 chore: add ts* files to lint --fix script 2024-07-26 09:06:54 -07:00
Kristin Aoki
3dfc579745 feat: add conditional for new parser beta testing (#496) 2024-07-26 10:59:40 -04:00
renovate[bot]
649863d094 fix(deps): update dependency @edx/frontend-lib-content-components to v2.5.2 (#1178)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-25 11:21:40 -04:00
renovate[bot]
1be693b826 fix(deps): update dependency npm to v10.8.2 2024-07-24 15:02:19 -07:00
renovate[bot]
0933bae314 chore(deps): update actions/checkout action to v4 2024-07-24 14:43:33 -07:00
Rômulo Penido
f159b2b31c chore: update frontend-build (#1155) 2024-07-24 21:42:03 +00:00
Rômulo Penido
25ab1fffa1 feat: adds filter by tags and contentType to library home (#1141)
Refactor to add search-manager feature.

Co-authored-by: Yusuf Musleh <yusuf@opencraft.com>
2024-07-24 12:13:24 -07:00
Milad Emami
ebab15f046 fix: correct typo in Alert component prop (#494)
Corrected the typo in the prop name of the Alert component from 'varaint' to 'variant'. This change ensures the proper functioning of the alert in informational variant.
2024-07-24 13:27:16 -04:00
Chris Chávez
77135cde1d feat: Library v2 components tab (#1109) 2024-07-22 18:04:57 -07:00
edX requirements bot
3a14141a4e chore: update browserslist DB (#1156)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2024-07-17 10:23:54 +02:00
Chris Chávez
3d24741062 feat: "Add content" sidebar on each library home page (#1065) 2024-07-17 10:15:40 +02:00
Rômulo Penido
e087001905 feat: create library (v2) form (#1116) 2024-07-12 05:54:37 -07:00
Braden MacDonald
cc41a2fda1 fix: source map warning seen during build (#1150) 2024-07-11 15:15:02 -04:00
renovate[bot]
5dee203401 fix(deps): update dependency @edx/frontend-lib-content-components to v2.5.1 (#1153)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-11 09:55:51 -04:00
Kristin Aoki
9bce0a34e3 fix: remove deprecated feedback link (#493) 2024-07-10 15:58:19 -04:00
renovate[bot]
085069abb0 fix(deps): update dependency @edx/frontend-lib-content-components to v2.5.0 (#1143)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-10 19:04:39 +00:00
Kyr
a22a260e27 feat: remove offset when stuio header exists (#491)
Co-authored-by: Kyrylo Hudym-Levkovych <kyr.hudym@kyrs-MacBook-Pro.local>
2024-07-10 14:35:25 -04:00
Kristin Aoki
b6ff6230e7 fix: text editor opening blank with no images (#492)
* fix: pasting and images only insert at beginning

* fix: add image click not showing gallery

* chore: increase code coverage

* fix: empty string when no srcs need updates

* fix: assest to static in raw editor
2024-07-10 13:53:40 -04:00
Braden MacDonald
ab9d57345b chore: remove unused fontawesome dependencies (#1149) 2024-07-10 14:05:02 +00:00
Rômulo Penido
71fcf9f168 fix: only show course blocks in the search modal (#1148) 2024-07-10 05:29:55 -07:00
Rômulo Penido
f60ddb579e feat: library home page ("bare bones") (#1076) 2024-07-10 05:20:00 -07:00
Braden MacDonald
117b4f10e7 chore: remove core-js and regenerator-runtime (#1032) 2024-07-10 05:07:29 -07:00
edX requirements bot
09822c2937 chore: update browserslist DB (#443) 2024-07-10 01:24:44 -07:00
Hunia Fatima
01d4b85205 perf: lockfile version check workflow file updated (#1107)
Co-authored-by: Hunia Fatima <hunia.fatima@A006-01315.local>
2024-07-10 11:05:43 +05:00
Yusuf Musleh
83489b0983 feat: Add filters/sorting for the libraries v2 tab on studio home (#1117) 2024-07-08 14:35:43 +00:00
Braden MacDonald
8cf26e1a75 Version bump for Paragon to 22.6.1, with stricter typing (#1146)
* fix(deps): update dependency @openedx/paragon to v22.6.1

* fix: lint errors from stricter types in new paragon version

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-08 10:10:08 -04:00
renovate[bot]
9528bfde62 chore(deps): update dependency meilisearch to ^0.41.0 (#1136) 2024-07-08 06:49:44 -07:00
Raymond Zhou
292663a5e3 Revert "fix(deps): update dependency @edx/frontend-lib-content-components to …" (#1142)
This reverts commit cdc9af2ed4.
2024-07-02 12:19:19 -04:00
renovate[bot]
9f0be768aa fix(deps): update dependency @edx/frontend-component-footer to v14.0.5 (#1121)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-01 17:11:05 +00:00
Kristin Aoki
efd73f9c0b fix: progress bar display for uploads (#1135) 2024-07-01 12:52:08 -04:00
renovate[bot]
cdc9af2ed4 fix(deps): update dependency @edx/frontend-lib-content-components to v2.4.3 (#1140)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-01 16:51:39 +00:00
Kristin Aoki
fc3cd9a9ce fix: image and paste insert (#490)
* fix: pasting and images only insert at beginning

* fix: add image click not showing gallery

* chore: increase code coverage
2024-07-01 12:29:05 -04:00
Kristin Aoki
eb3e6faba4 fix: update mapToStateProps to match changes in TinyMceWidget (#1133)
* fix: update mapToStateProps to match changes in TinyMceWidget

* feat: bump frontend-lib-content-components
2024-06-27 14:44:12 -04:00
Kristin Aoki
267823414e fix: simple editor without solution not loading (#489)
* fix: update initialize to only call required functions

* feat: update asset urls without asset object

* feat: add pagination to select image modal

* fix: lint errors

* chore: update tests

* fix: asset pattern regex match

* feat: update pagination to be button to prevent page skipping

* fix: e.target.error for feedback fields

* fix: failing snapshots

* fix: new simple problem load error
2024-06-27 12:54:59 -04:00
Braden MacDonald
a4859d2686 chore: convert all 'search-modal' code to TypeScript (#1129)
* chore: convert all 'search-modal' code to TypeScript

* fix: lint should check .ts[x] files too

* fix: remove unused dependency meilisearch-instantsearch
2024-06-27 12:54:01 -04:00
Kristin Aoki
22ea32cf01 feat: video upload progress modal (#1131)
* feat: add upload progress modal

* fix: increase code coverage

* fix: fix code to be more readable

* fix: delete empty file

* fix: failing test and lint

* fix: progress bar not updating

* feat: add missing abort controller on POST to edxVal
2024-06-26 18:00:07 -04:00
renovate[bot]
8b759bc867 fix(deps): update dependency @edx/frontend-lib-content-components to v2.4.1 (#1132)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-26 13:54:56 -04:00
bszabo
0e913739d4 Merge pull request #488 from openedx/revert-484-KristinAoki/improve-asset-loading
Revert "feat: improve asset loading"
2024-06-26 10:08:55 -04:00
bszabo
ba8141ea6a Revert "feat: improve asset loading (#484)"
This reverts commit f3ae225d64.
2024-06-26 10:02:59 -04:00
Kristin Aoki
9317b87564 Revert "feat: add upload progress modal (#1113)" (#1128)
This reverts commit 8ef804bd58.
2024-06-24 12:19:58 -04:00
Kristin Aoki
8ef804bd58 feat: add upload progress modal (#1113)
* feat: add upload progress modal

* fix: increase code coverage

* fix: fix code to be more readable

* fix: delete empty file
2024-06-24 10:53:49 -04:00
renovate[bot]
641419656f fix(deps): update dependency @edx/frontend-lib-content-components to v2.4.0 (#1118)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-24 09:02:05 -04:00
Jillian
6b6d3aaa7a Upgrade frontend-build to v14 (#1052)
* fix: warnings about Duplicate message id
* fix: paragon's Hyperlink no longer accepts a 'content' attribute
* test: ensure all act() calls are async
* test: Removed "async" from "describe"
* fix: DiscussionsSettings tests
* Don't nest userAction.click in act() -- nested act() statements have
  indeterminent behaviour.
* Use getBy* instead of findBy* with userAction to avoid nested act() statements
* Always await userEvent.click
* Use fireEvent.click when the onClick handlers need to be called
* Use queryBy* instead of getBy* when using .toBeInTheDocument or 
* fix: typo in data-testid
* test: Use useLocation to test route changes
* Don't nest userAction.click in act() -- nested act() statements have
* chore: fix lint:fix and lint errors
* remove "indent" setting from .eslintrc.js
* add @typescript-eslint/ prefix to eslint-disable-line statements where flagged by linter
* changed stylelint setting import-notation to "string"
* test: fix failing tests after upgrade
* fix: css error "target selector was not found"
* chore: upgrades dependency frontend-lib-content-components@2.3.0
* chore: bumps @edx/frontend-component-ai-translations to ^2.1.0

---------

Co-authored-by: Yusuf Musleh <yusuf@opencraft.com>
2024-06-22 00:14:46 +05:30
Braden MacDonald
28c7b32bd5 fix: don't accidentally bundle paragon CSS x2 2024-06-20 15:23:08 -07:00
Marcos Rigoli
3936737b48 feat: Include org filter when requesting LTI providers (#1114)
* feat: Include org filter when requesting LTI providers

* chore: Created silent version for CI testing to avoid log flooding
2024-06-20 11:17:08 -03:00
Yusuf Musleh
088a01d716 feat: Add lib v2/legacy tabs in studio home (#1050)
This PR adds a new configuration flag that shows/hides tabs in studio home along with some new functionality around to V1 and V2 Libraries.

When the new LIBRARY_MODE flag is set to "mixed" (default in dev) it will show "Libraries" and "Legacy Libraries" tabs that correspond to v1 and v2 tabs respectively.

When the new LIBRARY_MODE flag is set to "v1 only" (default in production) or "v2 only", only one tab "Libraries" is shown and only the respective libraries are fetched when the tab is clicked.

In addition to the above changes, the URL/route now updates when clicking on the tabs, and navigating to it directly would open up that tab as well as a new placeholder page that you will be redirected to when clicking on a v2 library if the library authoring MFE is not enabled.
2024-06-20 17:30:57 +05:30
vladislavkeblysh
c84e3229f6 feat: Validation for Start time and Stop time fields (#419)
* feat: fixed fields onblur

* feat: fixed fields onblur

* feat: added new tests
2024-06-18 16:51:32 -04:00
Dmytro
d2ddc9099f fix: Not used Number of attempts field (#473)
Co-authored-by: Dima Alipov <dimaalipov@MacBook-Pro-Dima.local>
2024-06-18 16:44:51 -04:00
Ihor Romaniuk
6ac0a6e562 fix: form group controls alignment (#423) 2024-06-18 16:40:49 -04:00
Navin Karkera
e2ed3bc7a7 refactor: show generic message on studio server error (#1112) 2024-06-18 16:07:46 -04:00
Adolfo R. Brandes
6a58779ffe Merge pull request #485 from arbrandes/update-codecov
build: Update codecov and use token
2024-06-17 11:57:12 -03:00
Kristin Aoki
f3ae225d64 feat: improve asset loading (#484)
* fix: update initialize to only call required functions

* feat: update asset urls without asset object

* feat: add pagination to select image modal

* fix: lint errors

* chore: update tests

* fix: asset pattern regex match

* feat: update pagination to be button to prevent page skipping

* fix: e.target.error for feedback fields

* fix: failing snapshots
2024-06-17 09:52:49 -04:00
Adolfo R. Brandes
74776b3663 build: Update codecov and use token
Update codecov to the latest version and start using the org-wide token for uploads.

See https://github.com/openedx/wg-frontend/issues/179
2024-06-14 11:44:01 -03:00
Jesper Hodge
db1250ee95 Revert "feat: flcc to 2.2.0 (#1106)" (#1111)
This reverts commit e22cce9fa6.
Reverts #1106

The reason is that the pipeline to deploy to stage broke. This commit is probably the reason.

The revert is temporary until the pipeline problem is solved.
2024-06-14 14:17:41 +00:00
Jillian
f20e5311a9 Fix some test warnings (#1062)
* fix: paragon's Hyperlink no longer accepts a 'content' attribute
* test: ensure all act() calls are async
* test: Removed "async" from "describe"
Returning a Promise from "describe" is not supported.
* fix: DiscussionsSettings tests
Previous commit revealed several issues with these tests
* Don't nest userAction.click in act() -- nested act() statements have indeterminent behaviour.
* Use getBy* instead of findBy* with userAction to avoid nested act() statements
* Use fireEvent.click when the onClick handlers need to be called
* Use queryBy* instead of getBy* when using .toBeInTheDocument or waitForElementToBeRemoved
  queryBy* return null when the element is not found.
* fix: typo in data-testid
Warning: React does not recognize the `data-testId` prop on a DOM
element. If you intentionally want it to appear in the DOM as a custom
attribute, spell it as lowercase `data-testid` instead.
* test: Use useLocation to test route changes
---------

Co-authored-by: Yusuf Musleh <yusuf@opencraft.com>
2024-06-13 10:37:26 +05:30
Raymond Zhou
e22cce9fa6 feat: flcc to 2.2.0 (#1106) 2024-06-12 12:42:00 -04:00
Bilal Qamar
252ad6a6b9 feat: updated frontend-build & frontend-platform major versions (#475) 2024-06-12 05:29:17 -04:00
Jillian
6760b75774 fix: warnings about Duplicate message id (#1061)
Fixes warnings about "duplicate message IDs", which seem to have been made by copy-paste errors.
2024-06-11 18:01:25 +05:30
Raymond Zhou
7f5e82a844 fix: handle null displayname (#1074) 2024-06-07 13:40:59 -04:00
Kristin Aoki
7aa2baaa8a fix: bump frontend-lib-content-components package (#1071) 2024-06-05 14:19:53 -04:00
Kristin Aoki
e543ccc2e1 fix: parser not saving unlimited attempts (#483)
* fix: default settings not loading for new problems

* fix: unlimited attempts not saving
2024-06-04 16:41:58 -04:00
Yusuf Musleh
8cde43eb5b fix: Search result redirect to unit lib component (#1027)
This change fixes redirection to the library component in the unit when selecting the search result. It also fixes an issue with navigating to the library MFE when selecting a library component.
2024-06-03 17:55:37 +05:30
Chris Chávez
460de7014e [FC-0042] Fix: Bug: Unusable "Languages" taxonomy appears in tagging drawer (#1031)
Hide language taxonomy when is empty
New message on search result when taxonomy is empty
Empty taxonomies message added in drawer
2024-06-03 17:36:54 +05:30
Kristin Aoki
9b4eb10342 fix: allow grace period minutes only (#1064)
* fix: allow grace period minutes only

* fix: zero minutes error
2024-05-31 15:30:00 -04:00
Kristin Aoki
a340320e8f fix: upgrade frontend -lib-content-componets package (#1060) 2024-05-31 09:56:03 -04:00
Kristin Aoki
a959c0543c fix: removal of content after problem type tags (#479)
* fix: removal of content after problem type tags

* fix: readability and error handling
2024-05-30 12:33:43 -04:00
Kristin Aoki
a585a13e97 fix: wrong lock status update message (#1053) 2024-05-28 11:52:39 -04:00
Kristin Aoki
435af2c36f fix: update date using utc timezone instead of local (#1043)
* fix: update date using utc timezone instead of local

* fix: lint error
2024-05-24 13:07:10 -04:00
Rodrigo Martin
732b7ed86c feat(AU-2035): Add disclaimer to AppSettingsModalBase (#1024) 2024-05-24 12:13:42 -03:00
Yusuf Musleh
d0b3328f26 feat: Import new taxonomy dialog flow (#1017)
This PR updates the existing import tags wizard to also handle  importing new taxonomies.
2024-05-24 19:19:26 +05:30
Chris Chávez
c3df0b0692 feat: Show toast when exporting course tags (#995)
Show in  in-progress toast when exporting course tags
2024-05-24 15:54:59 +05:30
Kristin Aoki
7247cc2d71 feat: bump frontend-lib-content-components 2.1.9 (#1028) 2024-05-22 15:40:04 -04:00
Kristin Aoki
3f987f9958 feat: improve error messaging and empty updates (#1025)
* feat: improve error messaging and empty updates

* chore: improve code coverage

* fix: update error messages

* fix: message title for saving handouts
2024-05-22 14:28:53 -04:00
Kristin Aoki
6c743f858d fix: video selection gallery scroll (#477)
* fix: video selection gallery scroll

* fix: lint errors
2024-05-22 12:02:25 -04:00
Peter Kulko
3647bcbbf9 fix: fixed rerun link (#1023)
* fix: fixed rerun link

* refactor: code refactoring

* refactor: updated tests

* refactor: after review
2024-05-21 12:58:53 -04:00
bszabo
54003af07c fix: issue-1018 remove reference to edX user\nIn configure wiki opera… (#1021)
* fix: issue-1018 remove reference to edX user\nIn configure wiki operation

* fix: issue-1018 keep to original they wording
2024-05-21 11:24:21 -04:00
renovate[bot]
f34157e11c fix(deps): update dependency @edx/frontend-lib-content-components to v2.1.8 (#997)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-16 14:26:42 +00:00
renovate[bot]
8a491cc365 fix(deps): update dependency @openedx/paragon to v22.4.0 (#963)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-16 14:15:18 +00:00
Leangseu Kim
7d9dd7535b chore: lock @edx/react-unit-test-utils 2024-05-16 10:02:50 -04:00
Ihor Romaniuk
7c539f346b fix: info icon shrinking on advanced settings page (#984) 2024-05-15 13:02:05 -03:00
ABBOUD Moncef
3315205d15 fix: video status badge translation (#438) 2024-05-13 15:26:07 -04:00
Navin Karkera
d882f2f856 feat: discussion setting and release & due date setting (#976)
* fix: hide release and due dates config in self paced courses

* feat: discussion enable setting for unit in outline

* refactor: message text

Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com>

* fix: modal dialog overflow

---------

Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com>
2024-05-13 11:21:18 -04:00
Leangseu Kim
65132eead2 fix: allow page grid to take plugin slot id instead (#994)
* fix: allow page grid to take plugin slot id instead

* chore: add config check

* chore: linting

* chore: variable more readable
2024-05-13 10:39:11 -04:00
Peter Kulko
a88066a2c5 fix: fixed course rerun route (#993) 2024-05-09 13:51:22 -03:00
Chris Chávez
e0fb41d8f5 [FC-0049] feat: Other Tags section added on tags drawer (#987)
Adds the new "Other tags" Section to tags drawer that contains the taxonomies/tags that the user doesn't have permission to see/edit. It allow to delete those tags.
2024-05-09 21:34:22 +05:30
Peter Kulko
55adcfe90d feat: Added errors handling 4xx, 5xx (#992)
* feat: [AXIMST-538] Add errors handling 4xx, 5xx

* fix: resolve discussions

* fix: second round of review discussions

refactor: fixing tests for Textbooks page

Co-authored-by: ruzniaievdm <ruzniaievdm@gmail.com>
2024-05-09 11:10:28 -03:00
ruzniaievdm
c884ff2882 fix: Group configurations - Add a counter for usage groups (#991) 2024-05-09 08:59:44 -03:00
Navin Karkera
5c1df3e16e feat: better api error handling (#972)
Improve API error handling.
2024-05-09 11:18:00 +05:30
Yusuf Musleh
8aea28c6e0 feat: search filters refinement (#980)
Sort blocktypes on hierarchy then alphabet.
2024-05-09 11:10:21 +05:30
Braden MacDonald
14245bc6ad feat: Enable taxonomy/tagging feature in MFE by default (#989)
* feat: enable tagging/taxonomy feature by default

* test: improve coverage

* chore: fix lint issue
2024-05-08 18:12:56 -03:00
Chris Chávez
dd9202fafe feat: prevent losing work when users click outside tag drawer after making edits [FC-0036] 2024-05-08 15:56:32 -04:00
Jillian
23fb68f2c3 feat: show "No tags added yet. [Add tags]" on the tag drawer (#988)
when we've expanded a taxonomy in read mode with no content tags added.
2024-05-08 16:47:39 -03:00
Chris Chávez
92b7ae1b77 feat: Add In progress message on import taxonomy (#953)
Message added as a toast
2024-05-08 16:44:21 -03:00
Navin Karkera
087c82c60c refactor: handle relative proctoring link (#974) 2024-05-07 12:01:41 +05:30
Chris Chávez
de408b5a3a [FC-0036] refactor: Further refinements to tag drawer (#970)
* refactor: Further refinements to tag drawer
* Padding to top and left tagging drawer
* Changes in headings in the tagging drawer
2024-05-06 14:46:46 +05:30
Bryann Valderrama
2f5d4f71ec feat: add ENABLE_GRADING_METHOD_IN_PROBLEMS feature flag (#932) 2024-05-03 10:54:52 -04:00
Chris Chávez
64be7e3b37 feat: Send messages after update tags (#975)
Updates the code of Tag Drawer to send two messages to parent (if the drawer is a iframe) when the tags are updated:

- One message with updated content tags.
- One message with the content tags count.
2024-05-03 20:04:42 +05:30
Navin Karkera
a63c808300 refactor: change expand-collapse arrows in outline (#973)
Set arrow down for expanded section/subsection and right arrow for
collapsed items same as legacy
2024-05-03 18:36:51 +05:30
Yusuf Musleh
6d9a8a1eac feat: search modal refinements (#959)
* feat: More spacing between search bar and selectmenu
* feat: Autofocus search field when modal opens
* feat: Fix issues with scroll to search result
This includes the following:
  - The target search element is aligned to the top of the page when scrolling to it
  - Makes sure the section/subsection is expanded in order to scroll to result
* fix: Match focus border radius with button's
* fix: Only expand (sub)section with search result
2024-05-03 15:02:22 +05:30
vladislavkeblysh
65f45f72f0 feat: [FC-0044] Textbooks Page (#890)
Implement Textbooks page.

---------

Co-authored-by: Glib Glugovskiy <glib.glugovskiy@raccoongang.com>
2024-04-30 18:38:43 -03:00
Peter Kulko
a9a73efbb6 feat: [FC-0044] Course unit - Drag and drop for xblocks (#908)
Implements drag and drop for xblocks in the unit page.
2024-04-30 11:21:51 -03:00
Rômulo Penido
e24fb7889e feat: redirect to unit page if the hit or its parent is a unit (#957)
This change adds the feature to redirect from a search result to a Unit, in case the hit parent is a Unit, or the hit is a unit itself.
2024-04-29 19:50:12 +05:30
XnpioChV
9327948b61 feat: [FC-0036] Refined tag drawer
It contains different changes to achieve the reading and editing mode of the drawer tag:

* Manage tags drawer footer with buttons added.
* Creation of ContentTagsDrawerContext.
* Creation of global state and global removed state to allow edit mode.
* Update API client to match with openedx-learning 0.9.1: Save tags of multiple taxonomies; to save all tags added/removed on edit mode
* Extract TagsTree and use it on the Tags Drawer.
* Update TagsTree to allow edit mode.
* Add a Toast on Tags Drawer; show the toast afert save.
* Scrolling + sticky footer on tags drawer
2024-04-25 15:29:13 -04:00
Yusuf Musleh
4146fa6c6e feat: Remove taxonomy export id prompt (#955) 2024-04-26 00:42:32 +05:30
Felipe Montoya
be71668b8d fix: removing ENABLE_NEW_EDITOR_PAGES flag (#951) 2024-04-25 08:35:45 -03:00
Peter Kulko
5686dee43b feat: [FC-0044] Course unit - Copy/paste functionality (#884)
Implement copy/paste.

Co-authored-by: monteri <36768631+monteri@users.noreply.github.com>
Co-authored-by: ihor-romaniuk <ihor.romaniuk@raccoongang.com>
2024-04-24 15:27:29 -03:00
Raymond Zhou
bef6796da4 fix: errors for positive time zones (#961) 2024-04-24 09:07:15 -07:00
Leangseu Kim
e55f031c39 chore: add slot to allow additional course app plugin (#941)
* chore: add @openedx/frontend-plugin-framework

chore: move plugin page setting button to a props

chore: split out app setting modal for reusability

chore: add implementation of WTC plugin

chore: update app setting form

chore: implement the plugin form with mock

chore: follow the UI design

chore: remove translation plugin and move it into frontend-plugin instead

* chore: add eslint ignore for env.config.jsx

* chore: update package-lock.json
2024-04-24 11:55:46 -04:00
connorhaugh
98138181f7 feat: add browser dialog to prevent navigation (#962)
Switching from undefined to "" tells the browser to put in a modal which requires users to confirm thier navigation away. this will prevent continued annoyances from upload failures: https://2u-internal.atlassian.net/browse/TNL-11587
2024-04-24 11:04:12 -04:00
Braden MacDonald
c32462e21e feat: Allow filtering by multiple tags [FC-0040] (#945)
As of #918 , the content search only allows filtering the results by one tag at a time, which is a limitation of Instantsearch.

So with this change, usage of Instantsearch + instant-meilisearch has been replaced with direct usage of Meilisearch. Not only does this simplify the code and make our MFE bundle size smaller, but it allows us much more control over how the tags filtering works, so that we can implement searching by multiple tags.

Trying to modify Instantsearch to do that was too difficult, given the complexity of its codebase.

Related ticket: openedx/modular-learning#201
2024-04-24 09:15:17 +05:30
Kristin Aoki
34104495c5 fix: adding files count in toast (#960)
* fix: adding files count in toast

* fix: toast to use plural function
2024-04-23 16:05:13 -04:00
ruzniaievdm
907ce50071 feat: [FC-0044] group configurations MFE page (#929)
* feat: group configurations - index page

* feat: [AXIMST-63] Index group configurations page

* fix: resolve discussions

* fix: resolve second round discussions

* feat: group configurations - content group actions

* feat: [AXIMST-75, AXIMST-69, AXIMST-81] Content group actions

* fix: resolve conversations

* feat: group configurations - sidebar

* feat: [AXIMST-87] group-configuration page sidebar

* refactor: [AXIMST-87] add changes after review

* refactor: [AXIMST-87] add changes after review

* refactor: [AXIMST-87] add changes ater review

---------

Co-authored-by: Kyrylo Hudym-Levkovych <kyr.hudym@kyrs-MacBook-Pro.local>

* fix: group configurations - the page reloads after the user saves changes

* feat: group configurations - experiment groups

* feat: [AXIMST-93, 99, 105] Group configuration - Experiment Groups

* fix: [AXIMST-518, 537] Group configuration - resolve bugs

* fix: review discussions

* fix: revert classname case

* fix: group configurations - resolve discussions

fix: [AXIMST-714] icon is aligned with text (#210)

* fix: add hook tests

* fix: add thunk tests

* fix: add slice tests

* chore: group configurations - messages

* fix: group configurations - remove delete in edit mode

---------

Co-authored-by: Kyr <40792129+khudym@users.noreply.github.com>
Co-authored-by: Kyrylo Hudym-Levkovych <kyr.hudym@kyrs-MacBook-Pro.local>
Co-authored-by: monteri <lansevermore>
2024-04-23 11:53:49 -04:00
Rômulo Penido
7f668a6ca4 refactor: remove old taxonomy page route (#954) 2024-04-23 14:52:17 +05:30
Ihor Romaniuk
6ec44b5f41 feat: [FC-0044] Unit page - Manage access modal (unit & xblocks) (#901)
* feat: [FC-0044] Unit page - Manage access modal (unit & xblocks)

* fix: add message description
2024-04-22 11:13:16 -04:00
sundasnoreen12
1834655399 fix: fixed scroll issue of provider and settings (#958) 2024-04-22 15:04:52 +05:00
Raymond Zhou
bfcac5c0dd feat: bump flcc (#956) 2024-04-18 15:24:54 -04:00
Raymond Zhou
e0b70f2b17 fix: HTML screen should expand with content (#474) 2024-04-18 14:48:10 -04:00
Chris Chávez
422a5db6f9 [FC-0036] feat: Sort taxonomies (#949)
Taxonomies are now sorted by tag count for those with applied tags, and by name for the rest.
2024-04-18 09:15:33 +05:30
Chris Chávez
08140226c3 [FC-0036] Refined tag drawer UI style (#947)
* feat: Remove 'x' close btn from tags drawer

* feat: Change style for taxonomy tags count

* feat: Update heading styles in tags drawer

* feat: Move dropdown arrows to left of taxonomy

---------

Co-authored-by: Yusuf Musleh <yusuf@opencraft.com>
2024-04-17 19:16:25 +05:30
Rômulo Penido
612d1d8c63 feat: improve search modal results [FC-0040] (#946)
This change makes improvements to the `SearchResult` component which shows the search results in a number of ways:

- It improves the information messages that show up before you start search, and if the results are empty. 
- It adds more context to the search results, by displaying the location of the content
- It adds a link to directly navigate to the relevant content item. 
- It adds an animated highlight to a unit right after you navigate to it. 

---------

Co-authored-by: Jillian <jill@opencraft.com>
Co-authored-by: Braden MacDonald <mail@bradenm.com>
2024-04-17 13:43:56 +05:30
Feanil Patel
b119671ee2 build: Update codecov and start using repo tokens.
Update codecove to the latest version and start using the per repo
tokens which will soon be required to get more reliable coverage builds.

This change also has a corresponding addition of a codecov repo upload
token to the repository secrets for this repo.
2024-04-16 11:55:55 -04:00
Jesper Hodge
0f440c6b3a Fix video upload failures (#952) 2024-04-15 16:49:07 -04:00
Braden MacDonald
2fda48fa5f Bump Paragon to v22.2.1, fix some bugs that turned up (#933)
* chore: bump paragon version

* chore: update snapshot test - alt moved from sr-only to aria-label
2024-04-12 14:05:56 -04:00
Kristin Aoki
63e220ee3e fix: change dropdowns to menus to fix off-screen render (#948) 2024-04-12 13:52:51 -04:00
Jhon Vente
2641aecc8a feat: home studio search filters (#846)
* feat: pagination studio home for courses

* chore: addressing some comments

* refactor: addressing pr comments

* test: adding test for studio home slice

* feat: search input and filters for course home

* fix: using open edx paragon

* feat: usedebounce hook for searching courses

* fix: filters params for searching coruses

* feat: adding coursekey when course name is empty

* chore: remove edit in studio button

* fix: message changed when courses were  not found

* refactor: support courses tab filters and pagination

* test: more cases for course filters component

* refactor: coverage for onsubmit search field

* test: unit test for courses tab component

* feat: loading for search input and layout of course tab

* fix: linter problems

* test: adding more tests for courses tab

* refactor: don't ignore empty string as a case for searching

* refactor: manage empty search bar as special case for searching

* fix: remove expected dispatch mock for clear button

---------

Co-authored-by: Maria Grimaldi <maria.grimaldi@edunext.co>
2024-04-11 16:25:19 -04:00
Braden MacDonald
fc3e38f63b feat: Content Search Modal: Filters [FC-0040] (#918)
Implementation of openedx/modular-learning#201

Implements a modal for searching course content with filters for searching in current or all courses, filtering by content type, content tags and text.
2024-04-11 10:01:06 +05:30
Raymond Zhou
aaf4989610 fix: react datepicker workaround for local time (#944) 2024-04-10 15:57:46 -04:00
Kristin Aoki
fd6b9ae3a6 fix: referencing activeStatus for undefined (#943) 2024-04-10 14:50:40 -04:00
Kristin Aoki
fdcda9833f feat: include usage locations in delete modal (#938) 2024-04-10 15:34:06 +00:00
Jesper Hodge
74eaaa1f9e chore: change github workflow file to not fail pipeline for codecov (#942) 2024-04-10 11:25:08 -04:00
Rômulo Penido
2adff6e51d feat: add content search modal [FC-0040] (#928)
* feat: Prototype search UI using Instantsearch + Meilisearch
---------

Co-authored-by: Braden MacDonald <braden@opencraft.com>
2024-04-08 21:39:15 +05:30
Dmytro
5634e9e507 fix: incorrect redirect link to Pages&Resources from Custom Pages (#916)
Co-authored-by: Dima Alipov <dimaalipov@MacBook-Pro-Dima.local>
2024-04-08 10:03:01 -04:00
Braden MacDonald
ced2c0e891 Fix the TaxonomyMenu test, which wasn't getting run at all (#930)
* test: fix the TaxonomyMenu test, which wasn't getting run at all
Co-authored-by: Rômulo Penido <romulo@opencraft.com>
2024-04-08 13:04:40 +05:30
Rômulo Penido
99a144a869 fix: message case (#924) 2024-04-06 09:00:27 +05:30
Yusuf Musleh
50d2577353 feat: Put Taxonomies tab behind flag (#937) 2024-04-05 12:01:52 -04:00
renovate[bot]
7f3164bbd7 fix(deps): update dependency @edx/frontend-lib-content-components to v2.1.6 (#935)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-04 20:24:38 +00:00
dependabot[bot]
3c64eb75aa chore(deps): bump axios from 0.27.2 to 0.28.1 (#936)
Bumps [axios](https://github.com/axios/axios) from 0.27.2 to 0.28.1.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v0.28.1/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.27.2...v0.28.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-04 20:12:36 +00:00
dependabot[bot]
3c74cd23b2 chore(deps-dev): bump axios from 0.27.2 to 0.28.0 (#848)
Bumps [axios](https://github.com/axios/axios) from 0.27.2 to 0.28.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v0.28.0/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.27.2...v0.28.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-04 16:00:55 -04:00
Kyr
e306b62dd1 feat: [FC-0044] Certificates page (#872)
* feat: [FC-0044]  Certificates page

* feat: add descriptions for details, signatories, sidebar i18n messages

---------

Co-authored-by: Kyrylo Hudym-Levkovych <kyr.hudym@kyrs-MacBook-Pro.local>
2024-04-04 13:28:04 -04:00
Jesper Hodge
dedcb14386 fix: trigger pipeline release for dependency fixes (#472) 2024-04-04 13:26:46 -04:00
dependabot[bot]
cf46e6c6c9 build(deps-dev): bump follow-redirects from 1.15.5 to 1.15.6 (#471)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.5 to 1.15.6.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.5...v1.15.6)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-04 13:04:17 -04:00
dependabot[bot]
77cdf2614e build(deps): bump express and @openedx/frontend-build (#470)
Bumps [express](https://github.com/expressjs/express) to 4.19.2 and updates ancestor dependency [@openedx/frontend-build](https://github.com/openedx/frontend-build). These dependencies need to be updated together.


Updates `express` from 4.18.2 to 4.19.2
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

Updates `@openedx/frontend-build` from 13.0.27 to 13.1.0
- [Release notes](https://github.com/openedx/frontend-build/releases)
- [Commits](https://github.com/openedx/frontend-build/compare/v13.0.27...v13.1.0)

---
updated-dependencies:
- dependency-name: express
  dependency-type: indirect
- dependency-name: "@openedx/frontend-build"
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-04 13:03:56 -04:00
dependabot[bot]
fd3c871585 build(deps): bump follow-redirects from 1.15.5 to 1.15.6 in /www (#469)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.5 to 1.15.6.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.5...v1.15.6)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-04 13:02:58 -04:00
dependabot[bot]
2bf04b8be6 build(deps-dev): bump webpack-dev-middleware from 5.3.3 to 5.3.4 (#468)
Bumps [webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware) from 5.3.3 to 5.3.4.
- [Release notes](https://github.com/webpack/webpack-dev-middleware/releases)
- [Changelog](https://github.com/webpack/webpack-dev-middleware/blob/v5.3.4/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-dev-middleware/compare/v5.3.3...v5.3.4)

---
updated-dependencies:
- dependency-name: webpack-dev-middleware
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-04 12:56:01 -04:00
dependabot[bot]
b61cb5c7cd chore(deps): bump express and @openedx/frontend-build (#931)
Bumps [express](https://github.com/expressjs/express) to 4.19.2 and updates ancestor dependency [@openedx/frontend-build](https://github.com/openedx/frontend-build). These dependencies need to be updated together.


Updates `express` from 4.18.2 to 4.19.2
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

Updates `@openedx/frontend-build` from 13.0.27 to 13.1.0
- [Release notes](https://github.com/openedx/frontend-build/releases)
- [Commits](https://github.com/openedx/frontend-build/compare/v13.0.27...v13.1.0)

---
updated-dependencies:
- dependency-name: express
  dependency-type: indirect
- dependency-name: "@openedx/frontend-build"
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-04 12:55:10 -04:00
dependabot[bot]
4ba62d7ee4 build(deps): bump webpack-dev-middleware from 5.3.3 to 5.3.4 in /www (#467)
Bumps [webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware) from 5.3.3 to 5.3.4.
- [Release notes](https://github.com/webpack/webpack-dev-middleware/releases)
- [Changelog](https://github.com/webpack/webpack-dev-middleware/blob/v5.3.4/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-dev-middleware/compare/v5.3.3...v5.3.4)

---
updated-dependencies:
- dependency-name: webpack-dev-middleware
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-04 12:52:44 -04:00
dependabot[bot]
0b1505975b chore(deps): bump follow-redirects from 1.15.5 to 1.15.6 (#902)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.5 to 1.15.6.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.5...v1.15.6)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-04 12:50:41 -04:00
dependabot[bot]
a9d33f612c chore(deps): bump webpack-dev-middleware from 5.3.3 to 5.3.4 (#917)
Bumps [webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware) from 5.3.3 to 5.3.4.
- [Release notes](https://github.com/webpack/webpack-dev-middleware/releases)
- [Changelog](https://github.com/webpack/webpack-dev-middleware/blob/v5.3.4/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-dev-middleware/compare/v5.3.3...v5.3.4)

---
updated-dependencies:
- dependency-name: webpack-dev-middleware
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-04 12:42:54 -04:00
Jesper Hodge
57d2fea5fd fix: set feature flag to default to false for pagination (#934) 2024-04-04 13:53:17 +00:00
Ihor Romaniuk
ffa0f14693 feat: [FC-0044] Unit page - display component support label (#913)
* feat: [FC-0044] Unit page - display component support label

* fix: add message description for tooltip of module support
2024-04-04 09:28:39 -04:00
Yusuf Musleh
806591f1cc feat: Add taxonomies tab in home page (#923) 2024-04-04 17:34:13 +05:30
Jhon Vente
fde3872e2e feat: pagination studio home for courses (#825)
This PR adds pagination for the studio home view and makes minor changes to each course card.

NOTE: This needs to be activated by the environment variable ENABLE_HOME_PAGE_COURSE_API_V2 otherwise, it will continue using the old course list

enable this feature flag
new_studio_mfe.use_new_home_page

* feat: pagination studio home for courses

* chore: addressing some comments

* refactor: addressing pr comments

* test: adding test for studio home slice

* chore: deleting unnecessary blank line

* feat: adding feature for pagination

* refactor: change customParams to requestParams

* fix: linter problems

* fix: course home number of 0 courses

* chore: update feature name for pagination

* fix: pagination enabled request and test for tab section added again

* chore: removing cms link in course card items

* chore: addresing some comments

* fix: array dependency for pagination
2024-04-03 11:38:05 -04:00
Ihor Romaniuk
5247ec5022 feat: [FC-0044] Unit page - make xblock edit functional (#912) 2024-04-02 16:15:09 -04:00
Kristin Aoki
dd13ed49aa feat: upgrade frontend-lib-content-components (#927) 2024-04-02 09:35:29 -04:00
Rômulo Penido
0a50bbc9ef fix: content tags drawer width (#910) 2024-04-02 12:40:14 +05:30
Raymond Zhou
d44edb84a0 feat: send content-length in video (#925) 2024-03-28 15:05:08 -04:00
Kristin Aoki
905bea0d59 fix: default setting not updating with updated default settings (#466) 2024-03-28 15:00:16 -04:00
Rômulo Penido
f57d40ea34 feat: tag sections, subsections, and the whole course (FC-0053) (#879)
* feat: tag sections, subsections, and the whole course
* docs: add comments to useContentTagsCount
2024-03-28 17:44:29 +05:30
Kristin Aoki
80bf86992d fix: transcript and thumbnail uploads (#914)
* fix: transcript and thumbnail uploads

* chore: add missing tests
2024-03-25 10:02:09 -04:00
Yusuf Musleh
1dde30a0a2 [FC-0036] feat: Make tags widget keyboard accessible (#900)
Adds the ability to navigate the new "Add Tags" widget using the keyboard, making it fully accessible through the keyboard.
2024-03-21 17:26:22 +05:30
Braden MacDonald
9a6e12bd3b Clean up Taxonomy API files/hooks/queries [FC-0036] (#850)
* chore: rename apiHooks.jsx to apihooks.js

* refactor: consolidate taxonomy API code

* fix: was not invalidating tags after import

* fix: UI was freezing while computing plan for large import files
2024-03-20 09:31:10 +05:30
Kristin Aoki
784a811ff8 Revert "feat: show alerts related files included via paste unit (#847)" (#909)
This reverts commit 071aee5b02.
2024-03-19 13:34:33 -04:00
Navin Karkera
071aee5b02 feat: show alerts related files included via paste unit (#847)
* fix: block highlight and status for unscheduled course

* feat: show alerts related to files after pasting unit

* refactor: rename paste notices and add view files option to alert

* refactor: remove additional visibility state check

* refactor: page alert message
2024-03-19 10:27:18 -04:00
Navin Karkera
da68fb8e9d feat: allow dragging blocks across parents in outline (#859) 2024-03-19 11:25:02 -03:00
Kristin Aoki
972a7f324c feat: upgrade frontend-lib-content-components (#906) 2024-03-18 16:44:07 -04:00
Kristin Aoki
4fa169556e fix: remove useEffect that fires before search params (#465)
* fix: remove useEffect that fires before search params

* fix: remove disable lint lines
2024-03-18 15:31:00 -04:00
Kristin Aoki
c809dfb2e4 feat: add pr template (#905) 2024-03-18 15:02:08 -04:00
Samir Sabri
1b2c65fae6 feat!: remove Transifex calls for OEP-58 (#627) 2024-03-18 15:01:20 -04:00
connorhaugh
b09729b55e fix: add new videos to the front of the videos list (#904) 2024-03-18 12:58:59 -04:00
connorhaugh
60917c6ab5 Feat: refactor upload thunk, no progress bar pt 2 (#899)
Attempts to fix: https://2u-internal.atlassian.net/browse/TNL-1141
2024-03-18 11:07:13 -04:00
Chris Chávez
d57ecc6779 [FC-0036] Tags Sidebar (#852)
* refactor: Unit sidebar to create the TagsSidebar

* feat: Structure of TagsSidebar and TagsTree

* feat: Adding styles to the TagsTree

* feat: TagsSidebarHeader created

* feat: Add count on TagsSidebarHeader

* test: Tests for new components added

* style: Update tags count with opacity when the count is zero

* refactor: Extract tag count component as generic

* refactor: Transform Sidebar to a wrapper component

---------

Co-authored-by: Rômulo Penido <romulo@opencraft.com>
2024-03-15 21:59:28 +05:30
connorhaugh
6ae9cdac00 Revert "feat: refactor upload thunk, no progress bar (#894)" (#895)
This reverts commit a88a88e9af.
2024-03-13 14:08:18 -04:00
Kristin Aoki
9740974bbd feat: add duplicate file validation for asset upload (#885)
* feat: add duplicate file validation for asset upload

* fix: modal only appearing once

* feat: add tests for overwrite modal

* fix: input not allowing second upload of same file

* fix: default pageSize for asset details
2024-03-13 12:09:00 -04:00
connorhaugh
a88a88e9af feat: refactor upload thunk, no progress bar (#894)
* feat: add progress bar for video uploads and refactor

---------

Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com>
2024-03-13 11:50:23 -04:00
connorhaugh
6baec5b6a3 Revert "feat: add progress bar for video uploads and refactor (#860)" (#893)
This reverts commit d76aaa73a4.
2024-03-13 10:18:05 -04:00
Peter Kulko
8acd27d7bf fix: replaced the LMS endpoint for navigating the course unit page
fix: [AXIMST-424] Course unit - Fixed network connection behavior (#138)

* fix: [AXIMST-424] fixed network connetcion behavior

* fix: added placeholder for unsuccessful loading for the page

* refactor: code refactoring
2024-03-13 10:56:10 -03:00
connorhaugh
d76aaa73a4 feat: add progress bar for video uploads and refactor (#860)
* feat: add progress bar for video uploads and refactor

---------

Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com>
2024-03-13 09:37:55 -04:00
Yusuf Musleh
4e70813fa9 [FC-0036] feat: New "Add Tags" widget (#834)
* feat: Use react-select for tags selector

Replace existing component with react-select component, by passing in
our custom component.
This retained the existing search functionality.

* fix: Fix missing deps causing constant rerender

This bug appeared after removing the react-query call to the backend
when selecting/unselecting a tag in the dropdown. Since it no longer
gets the updated state from the backend, it doesnt mask the bug.

The bug is essentially the `ContentTagsCollapsibleHelper` rerendering
causing the states to reset overriding the selected (not commited) tags.
This is due to missing dependancies in the useCallback.

* feat: Add stagedContentTags state in react-select

This adds a state and callbacks in the toplevel component of the content
tags drawer to be able to add/remove staged content tags and have them
showup in the react-select as selected chips.

* feat: Split up applied & staged content tags trees

Now content tags have seperate tree states for applied ones and staged
ones. They are updated seperately and both are used when updating the
selectable box UI. This allows for more flexibility with actions that
can be performed on the staged content tags with impacting the applied
ones.

* feat: Change style of implicit checkbox to checks

This overrides the indeterminate input checkbox style to match the
checked checkbox style, using variables defined in paragon.

* feat: Add bottom buttons in tags dropdown selector

* refactor: Remove cloneDeep + simplify code

* feat: Update placeholder/button texts

* feat: Implement cancel button + add proptypes

* feat: Implement commit/cancel staged tags

This implements the commit functionality for staged tags, taking account
for implicit tags. This also handles the case for removing applied tags
by clicking on the "x" in the TagBubble.

* feat: Keep all staged tags only commit explicit

* feat: Change style of add/cancel/load more buttons

* feat: Add inline "Add" button to commit tags

In the react-select component, an inline "Add" button showsup when some
tags are staged, if they are clicked they are commited/applied.

* fix: Keep applied tag checked when only staged child unchecked

* feat: Style add tags widget + staged tags

Also clear search term whenever tags are staged/cancelled

* feat: Fixed some typing errors

* test: Update tests to fix existing broken cases

* test: Add new functionality tests

* chore: add types to ContentTagsCollapsible

* chore: add types for useContentTagsCollapsibleHelper

* fix: Small bug with useIntl

* chore: Fix more linter issues

* refactor: Separate stagedTags and stagedTagsTree state updates

This refactor removed the warning that was caused because the state of a
parent component (ContentTagsDrawer) was being updated in the middle of
a state update in (ContentTagsCollapsible). This seperated the two state
updates to avoid this issue.

* chore: Update package-lock.json

* fix: Reset applied tags in selectbox when fetching

Whenever we get new applied tags from the backend, we reset the applied
tags that are checked, and only check the explicit tags. This was
causing an issue of duplicate applied tags being added to the selectbox.

* chore: Update package.json

---------

Co-authored-by: Braden MacDonald <braden@opencraft.com>
2024-03-13 18:57:30 +05:30
Maria Grimaldi
7f5687f175 refactor: address PR reviews 2024-03-12 16:42:11 -03:00
Maria Grimaldi
c8434b87c0 fix: import grouptypes from correct file 2024-03-12 16:42:11 -03:00
Maria Grimaldi
9299f4cf93 fix: import grouptypes from correct file 2024-03-12 16:42:11 -03:00
Maria Grimaldi
59d2dcaacb refactor!: put open manage team behind a configuration flag 2024-03-12 16:42:11 -03:00
Cristhian Garcia
42f8c3d95f chore: fix typo 2024-03-12 16:42:11 -03:00
Cristhian Garcia
9ff77945e3 chore: update open managed description 2024-03-12 16:42:11 -03:00
Cristhian Garcia
584823b879 fix: reorder groups 2024-03-12 16:42:11 -03:00
Cristhian Garcia
6e83e90cf0 feat: add open managed group type 2024-03-12 16:42:11 -03:00
Jeremy Ristau
ad7ba2f302 chore: update CODEOWNERS with new team (#888) 2024-03-12 11:57:23 -04:00
Ihor Romaniuk
bec59e5bbe feat: [FC-0044] Unit page - display xblock components (#857) 2024-03-12 11:48:11 -04:00
Jeremy Ristau
85ca350591 Merge pull request #463 from openedx/gh-team-update
chore: Github team update
2024-03-12 09:34:04 -04:00
Jeremy Ristau
d8503fbfe2 chore: update CODEOWNERS 2024-03-11 22:33:21 -04:00
Jeremy Ristau
9a8deced9b chore: update CODEOWNERS 2024-03-11 22:32:32 -04:00
Jeremy Ristau
1797707a9a chore: update openedx.yaml 2024-03-11 22:32:01 -04:00
Jesper Hodge
1fdddfb869 Fix replace broken selectable box component everywhere (#887)
The Configure Live modal in Pages & Resources page uses a selectable box to select the video conferencing tool. It seems broken as well (not selectable).

It looks like the bug with not working SelectableBox (see e.g. #886) affects pretty much any component that uses it.

Thus, this PR replaces every usage of the paragon component with our working copy from flcc.
2024-03-11 17:10:33 -04:00
Jesper Hodge
b5a287639d Fix SelectableBox problems (#886)
Due to a bug in the SelectableBox component, selecting values was not possible in different components throughout this MFE.

This fixes the Gallery and the Select Problem Types components by updating the FLCC version and replacing the SelectableBox copy with an import from FLCC.

For a full bug description see #880.
2024-03-11 17:09:58 -04:00
Jesper Hodge
7f73b895d1 fix: gallery (#462) 2024-03-11 15:43:35 -04:00
Jesper Hodge
679e15ed00 fix: gallery 2024-03-11 19:39:18 +00:00
Jesper Hodge
fb2a79985e Fix: selectable box in gallery (#461)
This fixes a bug where images and videos are not clickable when using the Gallery component.
Please see https://github.com/openedx/frontend-lib-content-components/pull/460 for a full description of the bug.
2024-03-11 15:26:54 -04:00
Jesper Hodge
b3b2881efb Revert "fix: gallery"
This reverts commit 736a786e12.
2024-03-11 18:42:17 +00:00
Jesper Hodge
736a786e12 fix: gallery 2024-03-11 18:41:17 +00:00
Jesper Hodge
be00028c4a Fix Problem Type Select (#460)
* fix: override selectablebox with copy of version from edx paragon 21.5.6

* chore: remove console logs

* fix: lint

* chore: update snapshots
2024-03-11 12:59:05 -04:00
renovate[bot]
dad4bd5282 fix(deps): update dependency @edx/frontend-component-footer to v13.0.4 (#881)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-11 10:25:27 -04:00
Jesper Hodge
17b1360c07 Fix: SortAndFilter modal doesnt respond to click (#880)
Description
We are encountering a bug in our stage environment that is very hard to reproduce locally, but not impossible. This is the same bug dealt with in several previous PRs like for example #871 (here I'm working on another component that uses the same paragon component and therefore encounters the same bug).

Since I was able to reproduce it locally, it is definitely not just a bug affecting only 2U-specific things.

Expected behavior
open a course with files
select a different sorting order (for example oldest to newest)
you should be able to select the different option
you should be able to successfully apply it
Actual behavior on stage environment
you can't select different option
you can't apply different option
Previous steps
Previously, I reproduced this locally by just adding the latest version of SelectableBox as a copy into this repo and importing it from there. Then, under the mistaken assumption that there was a missing context provider, I added that and it got fixed locally. However it turned out to not work on stage.

Measures taken in this PR
I replaced the entire SelectableBox component with all subcomponents with a version from @edx/paragon@21.5.6, which was apparently the version in the commit that didn't have the error yet. In theory, this would just fix the problem, though I have my doubts. But it's worth a try. I only imported it in one place, in this SortAndFilter modal.
I added console logging for onChange events which seem to the problem, as they are not triggering a change in the value of the context on stage. I see little choice than to log them to get more info. This will only affect the component that's not working.
2024-03-08 17:44:03 -05:00
Chris Chávez
c39b52a6bf [UU-58] Implement tagging & taxonomy feature in outline (#855)
* feat: TagCount component

* feat: Update ContentTagsDrawer to use it in the MFE

* feat: Manage tags menu added on units

* feat: Tag count added on unit

* feat: Add button feat to Tag count

* test: Course Outline api tests

* test: Ignore lines that can not be tested

* style: Comment added on ContentTagsDrawer

* style: Nits on CardHeader
2024-03-08 10:00:51 -05:00
PKulkoRaccoonGang
642b4e4052 refactor: refactoring after review 2024-03-08 08:17:54 -03:00
PKulkoRaccoonGang
423a3f3f72 fix: [AXIMST-470] fixed sidebar status after deleting or duplicating xblock 2024-03-08 08:17:54 -03:00
PKulkoRaccoonGang
f1f036576e refactor: after rebase 2024-03-08 08:17:54 -03:00
PKulkoRaccoonGang
deb76a0609 fix: [AXIMST-473] fixed sidebar publish status 2024-03-08 08:17:54 -03:00
PKulkoRaccoonGang
912c42e802 fix: [AXIMST-472] fixed sidebar visibility notification 2024-03-08 08:17:54 -03:00
PKulkoRaccoonGang
bdd641225f fix: [AXIMST-427] fixed unpublished changes alert 2024-03-08 08:17:54 -03:00
Peter Kulko
9021fccdb7 feat: [AXIMST-25] Course unit - Alert notification about unpublished changes (#135)
* feat: [AXIMST-25] added alert notification about unpublished changes

* feat: added tests

* feat: added translations
2024-03-08 08:17:54 -03:00
Peter Kulko
e4d88fb1fa feat: [AXIMST-24] Course unit - Sidebar buttons functional (#134)
* feat: [AXIMST-24] sidebar buttons functional

* refactor: removed modal extra className

* refactor: refactoring after review
2024-03-08 08:17:54 -03:00
Peter Kulko
073e191273 feat: [AXIMST-23] Course unit - Sidebar with unit info (#117)
* feat: added Sidebar with unit info

* feat: added unit location

* refactor: added legacy behavior

* feat: added live variant

* refactor: code refactoring

* feat: added tests and translations

* feat: added new font size

* refactor: after review
2024-03-08 08:17:54 -03:00
Ihor Romaniuk
f8095e6670 feat: [FC-0044] Unit page - display xblock components 2024-03-08 08:17:54 -03:00
Kristin Aoki
e4c3997d17 fix: revert addition of course-ingestion-tool submodule (#878) 2024-03-07 16:42:46 -05:00
Kristin Aoki
da7fe95f24 fix: accessibility page config reference (#875) 2024-03-07 16:11:04 -05:00
Jesper Hodge
896969c7de Fix radio context provider missing (#874)
This is a temporary fix for a bug that stems from a paragon component, SelectableBox. So we're using our own copy from fronten-lib-content-components.
2024-03-07 15:55:30 -05:00
Jesper Hodge
5069cf8638 fix: problem type not selectable (#459)
JIRA: https://2u-internal.atlassian.net/browse/TNL-11465

This is a problem we're experiencing on stage due to a bug in paragon. This is intended as a temporary fix until we can dig into why this is happening in paragon. But basically the Context for the SelectableBox is missing a provider in paragon. The short-term fix is to copy over paragon's selectablebox component and fix it. This is done so that our quick fix doesn't break anything else in paragon for now or cause any unexpected issues.
2024-03-07 15:21:02 -05:00
Kristin Aoki
8100281fb4 feat: add checklist page (#870)
* feat: add checklist page

* fix: failing tests

* fix: styling bugs

* fix: lint errors

* feat: add test fro CourseChecklist

* fix: lint errors

* feat: add ChecklistSection tests

* fix: lint error

* fix: missing api reply status
2024-03-07 15:20:33 -05:00
Jesper Hodge
f035391c2f fix: replace paragon radio select set with copy to debug (#871)
step 1 for trying fixes for the stage bug where the paragon radio select is not clickable. Here I just replace the paragon component with our identical copy to see what that changes. Followup steps are to change this component until hopefully the problem gets fixed.
2024-03-06 16:26:17 -05:00
Eugene Dyudyunov
3607e6423d fix: correct internal routing
The Content dropdown items have incorrect URLs for the
internal routing when MFEs are deployed using the common
domain and the PUBLIC_PATH.
2024-03-06 10:00:35 -03:00
Jesper Hodge
4395607074 chore: update frontend-lib-content-components to 2.1.0 to fix problem select (#867) 2024-03-05 13:03:07 -05:00
Kristin Aoki
f717cdac86 feat: add accessibility page (#861)
* feat: add accessibility page

* fix: lint errors

* feat: increase code coverage

* fix: lint errors
2024-03-05 12:15:58 -05:00
Jeremy Ristau
40c9d6ee0d chore: update tnl team name (#862) 2024-03-05 09:19:39 -05:00
Jeremy Ristau
4e78c07dac Merge pull request #458 from openedx/catalog-info-updates
chore: update tnl team name
2024-03-05 09:19:33 -05:00
Jeremy Ristau
e5a469f7ea chore: update tnl team name 2024-03-04 21:46:23 -05:00
Braden MacDonald
3c661e15cb Convert "Pages & Resources" page to a plugin system (#638)
* feat: Make "Pages & Resources" course apps into plugins

* feat: move ora_settings

* feat: move proctoring

* feat: move progress

* feat: move teams

* feat: move wiki

* feat: move Xpert settings

* fix: add webpack.prod.config.js

* fix: clean up unused parts of package.json files

* feat: Add an error message when displaying a Course App Plugin fails

* chore: fix various eslint warnings

* chore: fix jest tests

* fix: error preventing "npm ci" from working

* feat: better tests for <SettingsComponent>

* chore: move xpert_unit_summary into same dir as other plugins

* fix: eslint-import-resolver-webpack is a dev dependency

* chore: move learning_assistant to be a plugin too

* feat: for compatibility, install 2U plugins by default

* fix: bug with learning_assistant package.json
2024-02-28 11:50:54 -05:00
PKulkoRaccoonGang
49fce4622c refactor: tests refactoring 2024-02-27 14:50:06 -03:00
Chris Chávez
608b2f79f8 [FC-0036] Refined taxonomy details page (#833)
* UX refinements on tag list table
* Add page size to tag list table
* fix Datatable pagination
2024-02-27 21:02:06 +05:30
PKulkoRaccoonGang
6b57ce3e53 refactor: refactoring after review 2024-02-27 11:44:42 -03:00
Peter Kulko
6aff1c1168 feat: [AXIMST-19, 20, 22] Course unit - Modal windows for course unit page components (#118)
* feat: added modal windows for course unit page components

* refactor: code refactoring

* refactor: added translations

* refactor: refactoring after review

* refactor: after review
2024-02-27 11:44:42 -03:00
Ihor Romaniuk
2b11df9eb5 fix: [AXIMST-371] fix correct internal route on create new unit (#114) 2024-02-27 11:44:42 -03:00
Peter Kulko
7fcc501d2e feat: Unit creation button logic and refactoring 2024-02-27 11:44:42 -03:00
Jeremy Ristau
90fb3d8edc chore: add missing maintainership files (#840)
* chore: add catalog-info file for Open edX Backstage

* chore: Create CODEOWNERS
2024-02-27 06:41:21 -05:00
Rômulo Penido
0fc0ce0829 feat: add export course tags menu (#830)
This change adds an item in the Tools menu to export the course tags to a CSV file.
2024-02-21 12:50:40 +05:30
Braden MacDonald
16d2f38325 Display full descendant count on taxonomy tag list page [FC-0036] (#826) 2024-02-20 15:40:30 +05:30
Jhon Vente
90d5ac4ffc feat: TinyMCE plugin insert iframe (#427) 2024-02-16 14:02:34 -05:00
Brian Smith
76bb8e88c1 chore(deps): update paragon and frontend-build to openedx scope 2024-02-16 13:40:03 -03:00
Ihor Romaniuk
51c5f9c4dc refactor: Unit page - refactoring breadcrumbs, view live and preview links buttons (#827) 2024-02-14 13:38:54 -05:00
Navin Karkera
60c1a0343c feat: proctoring & prerequisite settings and page alerts (#816)
* feat: add proctoring exam link to actions

* feat: prerequisite settings in advanced tab

* refactor: use formik for configuration modal in outline

* feat: proctoring exam settings in subsection configuration

test: prereq & proctoring settings

* feat: outline alerts

test: outline page alerts

* refactor: replace highlights badge with bubble

* feat: discussion badge in outline

* refactor: status bar style and date format

* Fix spacing between checklist and highlights button
* Fix title alignment in status bar
* Align learn more link to center with respect to button
* Update start date display in local format

* fix: unit url

* refactor: redesign item header

* move status to end of card
* move edit icon next to title
* make it visible on hover

* test: improve coverage

* refactor: update messages and alert colors
2024-02-13 16:32:32 -05:00
Brian Smith
f33a3b5521 fix(deps)!: support paragon and frontend-build in openedx scope (#457)
BREAKING CHANGE: frontend-platform peer dependency updated to ^7.0.1
BREAKING CHANGE: @edx/paragon peer dependency updated to @openedx/paragon
2024-02-09 14:41:16 -05:00
Ihor Romaniuk
1555e9f88e feat: [FC-0044] Unit page - add new component section (#828)
* feat: Course unit - add new component section

* feat: Course unit - make Discussion and Drag-and-Drop button functional

* feat: Course unit - make Problem button functional

* feat: Unit page - make Video button functional
2024-02-09 14:27:00 -05:00
Chris Chávez
3938015aaa feat: Add export ID on Taxonomy details and import new Taxonomy (#814)
Adds a new prompt on the import new taxonomy workflow to enter the export_id, and adds the export_id on the Taxonomy page details.

Implements  modular-learning#183 '[Tagging] An "Export ID" identifies each Taxonomy'
2024-02-09 09:27:17 +05:30
Feanil Patel
62bff35fcd Merge pull request #381 from Mashal-m/mashal-m/update_lockfile
refactor: updated lock file version check to use new workflow
2024-02-08 14:30:16 -05:00
Rômulo Penido
a318c322b2 fix: revert code due to wrong merge conflict resolution (#824) 2024-02-08 21:48:07 +05:30
Peter Kulko
b234344aab feat: [FC-0044] Course unit page - Unit switch widget with a New unit creation button (#809)
* feat: added Unit switch widget with a New unit button

* refactor: refactoring after review

* refactor: changed the variable name
2024-02-08 10:15:21 -05:00
Adolfo R. Brandes
4850302175 fix: Runtime config support for feature flags
This makes sure the following feature flags work with dynamic runtime
configuration:

* ENABLE_NEW_EDITOR_PAGES
* ENABLE_UNIT_PAGE
* ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN
* ENABLE_TAGGING_TAXONOMY_PAGES

We also remove flags from the `.env*` files that are no longer in use.
2024-02-06 16:05:28 -03:00
Navin Karkera
815ddbe94e feat: copy & paste units
refactor: paste component

fix: lint issues and delete unused hook

test: add test

fix: update api for npm broadcast channel
2024-02-05 14:01:38 -05:00
Navin Karkera
2cb907e731 feat: xblock status component
feat: add custom relative dates flag to state

refactor: add gated status type

refactor: alert style

feat: add status text to units

test: add tests

fix: lint issues

refactor: break up xblock status component

fix: selector for isCustomRelativeDatesActive

fix: prereq default value
2024-02-05 14:01:38 -05:00
Ihor Romaniuk
9c52b8b6c5 feat: [FC-0044] Unit page header section (#808)
* feat: create Unit page and add page header functionality

* fix: after code review

---------

Co-authored-by: monteri <lansevermore>
2024-02-05 11:58:35 -05:00
Omar Al-Ithawi
056a15bedb feat: tutor-mfe compatiblilty for atlas pull (#817)
- install atlas
 - remove `--filter` to pull all languages by default
 - use ATLAS_OPTIONS to allow custom `--filter`
 - include frontend-platform, ai-translations and lib-contents in `atlas pull` command

Refs: FC-0012 OEP-58
2024-02-02 14:16:01 -05:00
Kristin Aoki
18537e3f62 fix: model update for usage locations (#819) 2024-02-02 11:21:44 -05:00
Rômulo Penido
24c48bc3ea feat: add search highlight/expand and "no tags" message (#799)
This change makes minor improvements in the search taxonomy UI.  It expands taxonomies that match the search and highlight the search term, and adds a "No tag found with search term '....'" message.
2024-02-02 20:39:30 +05:30
Jillian
49d4fd44a3 fix: fixed typo in updateContentTaxonomyTags URL [FC-0036] (#815)
* fix: fixed typo in updateContentTaxonomyTags URL
* fix: use params instead of urlencoding
2024-02-02 12:00:04 +05:30
Braden MacDonald
c7aef6e467 fix: minor TypeScript error - not sure how it got onto master 2024-02-01 01:43:48 +05:30
Braden MacDonald
d6338de8bc docs: fix incorrect waffle flag stated. 2024-02-01 01:43:48 +05:30
Jillian
b56b5d9b16 Use object permissions in Tagging frontend [FC-0036] (#787)
Uses the permissions added to the Tagging REST API by openedx/openedx-learning#138 to decide what actions (e.g. import, export, edit, delete) to present to the current user when viewing Tagging-related content.
2024-01-29 14:47:31 +05:30
Kristin Aoki
90bc242ddd fix: update video page load order (#810)
* fix: asset card/row menu appearing for videos

* fix: page load time

* fix: video status messages
2024-01-25 17:04:34 -05:00
dependabot[bot]
f8aa157c93 chore(deps): bump follow-redirects from 1.15.1 to 1.15.5 (#806)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.1 to 1.15.5.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.1...v1.15.5)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-24 17:19:11 -05:00
Syed Ali Abbas Zaidi
34fbadfd6a feat: migrate enzyme to RTL (#770) 2024-01-24 16:57:28 -05:00
Syed Ali Abbas Zaidi
dcdaace08d feat: migrate enzyme to edx react-unit-test-utils 2024-01-24 16:51:53 -05:00
Michael Roytman
6d431e5746 Add settings modal for Xpert Learning Assistant feature. (#794)
* feat: modify AppSettingsModal to add bodyChildren prop and to make the learnMoreText prop optional

This commit adds a new bodyChildren prop to the AppSettingsModal component. This prop is meant to be used by a parent to pass through React components that should be rendered between the enable toggle and the form. This allows parents to specify additional UI that doesn't belong in the form. For example, additional documentation about the feature or additional links are examples of additional UI that can be rendered this way.

This commit modifies the learnMoreText prop to the AppSettingsModal component optional. The learnMoreText prop is used as the text for the "learn more configuration" link. This link is rendered only if the corresponding documentationLink is provided, and this link is optional. Therefore, the corresponding learnMoreText prop should also be optional.

* feat: modify PagesAndResources to support additional pages in the "content permissions" section

This commit modifies the way that the PagesAndResources component renders pages in the "content permissions" section to enable additional pages in this section beyond just the Xpert unit summaries feature.

* feat: add settings modal for Xpert Learning Assistant feature

This commit adds a settings modal for the Xpert Learning Assistant feature.
2024-01-24 12:00:17 -05:00
Jorg Are
9e06065fd3 feat: replace ai translations edx component with the openedx version (#803) 2024-01-24 17:48:49 +01:00
Navin Karkera
09eef604f7 refactor: replace time picker by text box in advanced tab 2024-01-24 09:50:16 -05:00
Navin Karkera
5a2dbad343 test: improve coverage for section, subsection & unit configuration 2024-01-24 09:50:16 -05:00
Moncef Abboud
13cb1d3539 feat: add unit configuration modal 2024-01-24 09:50:16 -05:00
Navin Karkera
5a27d50d2a refactor: use time picker in advanced tab
fixes issues related to form autosuggest

fix: hide header only for advanced tab time picker
2024-01-24 09:50:16 -05:00
Stephannie Jimenez
ffec32cba8 feat: add subsection configuration modal
test: add render and API tests

fix: fix non saving options and add review style changes

fix: remove additional tab in the section configuration

fix: remove isSubsection state, fix css issues and fix tests

fix: add review changes, fix advanced tab hour selection and update tests

test: fix failing test in courseOutline.test.jsx

fix: remove unused state, add TODO comment, fix stack rendering and NaN values

feat: show previous state in autosuggest if an invalid option is provided and fix warnings

test: fix failing test
2024-01-24 09:50:16 -05:00
Navin Karkera
53118a4e0b feat: move up & down menu action for sections, subsections & units
test: add tests for move options

refactor: disable move option instead of hiding

fix: incorrect variable name in tests

feat: move up & down menu action for units

test: add tests for unit move options
2024-01-24 09:50:16 -05:00
Sid Verma
d2f63b8b16 feat: Add drag-n-drop support to course unit, refactor tests.
chore: address review feedback
2024-01-24 09:50:16 -05:00
Navin Karkera
0e829974ef feat: add colored left border to items in course outline
refactor: move common styles to conditional sortable element
2024-01-24 09:50:16 -05:00
Navin Karkera
eb0c61ce6d refactor: course outline badge status logic 2024-01-24 09:50:16 -05:00
Navin Karkera
b417cd64a0 feat: use actions and other flags to control item actions
Uses action flags from API to control display of delete, duplicate, child new button and dragging.
Use isHeaderVisible flag to control display of subsection headers.

All these changes prepare outline for entrance exam section display.

feat: use actions flags for subsections

test: actions
2024-01-24 09:50:16 -05:00
Sid Verma
70b4795650 feat: Add drag and drop support to subsections
feat: Update tests, fix bugs in drag and drop elements

chore: address review feedback
2024-01-24 09:50:16 -05:00
Rômulo Penido
3842b046cd fix: minor react errors in course authoring mfe [FC-0036] (#789)
* fix: remove console warnings and add missing typing checks
* fix: TagData <> TagListData swap names
* fix: toast needs show property
* fix: remove type guard from tagsCount
* fix: apply suggestions from code review
Co-authored-by: Jillian <jill@opencraft.com>
2024-01-24 16:59:33 +05:30
Raymond Zhou
c2ad1b8c99 fix: error handling for save api call (#805) 2024-01-23 15:55:24 -05:00
Kristin Aoki
bdb4ffe69d fix: gallery card text and load (#795) 2024-01-16 17:06:50 -05:00
Kristin Aoki
0a053d32ce feat: add missing transcript setting update date (#793) 2024-01-16 16:32:37 -05:00
Kristin Aoki
859819f0f0 feat: bump frontend-lib-content-components (#798) 2024-01-16 16:15:48 -05:00
Kristin Aoki
1bc4e51c22 fix: url for video uploads (#453)
* fix: url for video uploads

* fix: possible undefined error in postUrlRedirect
2024-01-16 11:00:43 -05:00
Navin Karkera
008d619236 feat: video sharing option dropdown (#779)
* feat: video sharing option dropdown

* test: video sharing option

* fix: lint issues

* refactor: messages for video sharing options

* test: add failure test for video sharing

* refactor: rename course block api url
2024-01-16 10:50:16 -05:00
Rômulo Penido
b59ecafc83 feat: refined ux update a taxonomy by downloading and uploading [FC-0036] (#732)
This PR improves the import tags functionality for existing taxonomies implemented at #675.

Co-authored-by: Jillian <jill@opencraft.com>
Co-authored-by: Braden MacDonald <mail@bradenm.com>
2024-01-16 12:00:15 +05:30
Rômulo Penido
1fef358f55 feat: assign taxonomy to organizations [FC-0036] (#760)
This PR adds a UI to assign organizations to a Taxonomy.

Co-authored-by: Jillian <jill@opencraft.com>
2024-01-12 13:10:56 +05:30
Kristin Aoki
bfcd3e6ff9 fix: mov files not being allowed on video upload (#792) 2024-01-11 12:19:09 -05:00
Kristin Aoki
433a87795c feat: bump frontend-lib-content-components (#791) 2024-01-11 10:18:26 -05:00
connorhaugh
a3975f47e2 fix: dont allow course detail page to break editor (#790)
At the moment, editors served from V1 libraries are broken because they use the course authoring MFE url (because they use editors in the same way courses do).
2024-01-11 09:44:29 -05:00
Kristin Aoki
4653322fca fix: video upload api fetch body (#454) 2024-01-10 17:13:29 -05:00
Jesper Hodge
0debaecad6 fix: export page timestamp (#785)
* fix: export page timestamp

* fix: tests
2024-01-10 16:59:50 -05:00
Kristin Aoki
97da4d1d61 fix: video upload api body and error control (#782) 2024-01-10 10:29:33 -05:00
Navin Karkera
faf90d1fa7 feat: unit list
refactor: hide tooltip based on arg

refactor: card header to include title link

feat: delete unit option

feat: duplicate unit option

refactor: title click handler name and remove unwanted scss properties

test: new unit and edit unit option

test: add delete unit and combine it with section and subsection test

test: add duplicate unit test and combine it with section & subsection test

refactor: replace act call by oneline

test: add publish unit & subsection test and combine it with section test

refactor: add jest-expect-message to add custom msg to tests

fix: lint issues

test: fix unit card tests

refactor: remove unnecessary css and message

refactor: pass title as component to card header

refactor: extract status badge to a component

fix: lint issues

refactor: rename status badge component

test: fix card header tests

refactor: new item button styling

feat: show loading spinner while sections are loading

refactor: new button style
2024-01-10 09:38:23 -05:00
Braden MacDonald
1e23ce1062 fix: react-router basepath was not set, breaking this MFE on tutor instances (#784) 2024-01-10 18:59:50 +05:30
kenclary
9ad192054b fix: configure webpack to fix paid powerpaste plugin (#783) 2024-01-09 16:15:34 -05:00
Kristin Aoki
bee3758d18 feat: update usage location call (#764) 2024-01-09 12:18:03 -05:00
Kristin Aoki
cae7f9bc22 feat: bump frontend-lib-content-components (#780) 2024-01-08 14:28:37 -05:00
Yusuf Musleh
138f1d29df feat: Add v2 lib components content tags support (#771)
Add support for fetching content data for Library V2 components in content tags drawer.
2024-01-08 15:12:32 +05:30
Rômulo Penido
6c0fc09075 feat: add import taxonomy feature [FC-0036] (#675)
This change adds a new button in the Taxonomy List to allow users to create new taxonomies by importing a CSV/JSON file.
2024-01-08 12:38:03 +05:30
Kristin Aoki
13f039ae4c feat: add blockId to return url (#442) 2024-01-05 09:30:35 -05:00
ayesha waris
2205506b26 chore: removed reported_content_email_notifications_flag dependency (#775) 2024-01-05 17:01:18 +05:00
Jesper Hodge
8833f7bfca fix: library editor not working locally (#448)
Internal issue: https://2u-internal.atlassian.net/browse/TNL-11299

In library-authoring, content blocks could not be edited locally due to some problem with the Accept header. This caused some 404s. Visually you would get an infinite loading spinner.

This depends on openedx/frontend-app-library-authoring#399.
2024-01-04 14:36:07 -05:00
Artur Gaspar
2e070c9a12 feat: error page on invalid course key (#761) 2024-01-04 10:28:19 -05:00
Kristin Aoki
52b75e0b06 fix: uploading progress percentage (#763) 2024-01-04 09:36:17 -05:00
Yusuf Musleh
278862127b feat: Add filter taxonomies by org (#755)
This implements filtering taxonomies on the taxonomy list page by selecting organization name, all taxonomies, or unassigned taxonomies.
2024-01-04 17:50:32 +05:30
Jesper Hodge
70581c54ab refactor: abstract XML parser output operations (#445)
This is a refactoring for a part of the ReactStateXMLParser. I wanted to use functions that are more generic and not just handle a list of edge cases. So I encapsulated the operation that was done in this part of the code to a function `findNodesAndRemoveTheirParentNodes` which is more generic and could be used for different operations.
2024-01-02 15:04:03 -05:00
renovate[bot]
4ffebdac77 fix(deps): update dependency @edx/frontend-lib-content-components to v1.177.9 (#762)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-21 11:37:04 -05:00
kenclary
69452344d8 Merge pull request #447 from openedx/kenclary/plugins
fix: update public plugins repo version
2023-12-21 11:13:10 -05:00
Ken Clary
8fdb395680 fix: update public plugins repo version 2023-12-21 11:09:29 -05:00
Jesper Hodge
782faddbf8 chore: update flcc to version 1.177.8 (#759) 2023-12-20 17:52:16 -05:00
Jesper Hodge
e77d3d1014 fix: do comment change to trigger release (#446) 2023-12-20 17:23:46 -05:00
Jesper Hodge
50c580cca2 fix editor deleting description (#444)
internal issue: https://2u-internal.atlassian.net/browse/TNL-11311

This fixes a bug where the editor was deleting the OLX tag when editing in the simple editor and then saving.
Also the description was being converted to em for the simple editor, but then not converted back. However, the xblock renders label and then em in reverse order for some reason.
To fix it, the em gets converted back to description now, but not for every em tag (added a class "olx_description" for the tags that should be converted).
2023-12-20 16:44:27 -05:00
Navin Karkera
df532b36ab test: improve coverage for course outline
refactor: remove delete unit hook and thunk till unit list is implemented

test: additional tests for sections

test: additional tests for subsections

test: replace query calls by button clicks
2023-12-20 10:20:48 -05:00
Navin Karkera
b0cb53ab44 refactor: reuse drag-n-drop component from lib-components
refactor: subsection and drag component style

refactor: subsection styling

refactor: generalize message ids for card header
2023-12-20 10:20:48 -05:00
Navin Karkera
580b8cbdb4 fix: handle scrolling with drag-n-drop
test: update tests

fix: scroll to element only when required

test: fix subsection component render

refactor: use textarea for highlights
2023-12-20 10:20:48 -05:00
Stephannie Jimenez
48ab324100 feat: add drag n drop functionality to section cards
feat: use react-dnd library for drag and drop implementation

style: fix linting issues

fix: finalize section order on drop instead of hover

fix: prevent same index drag to start request and restore state on error

fix: restore sectionlist order

fix: prevent drag event while editing the text

style: fix linting issues

test: fix failing tests

test: add missing hooks to SectionCard component in test

test: add wrapping to SectionCard test component

test: add tests for checking the API that sets the ordering

fix: merge scroll-to-bottom with drag and drop implementations

fix: fix linting issues
2023-12-20 10:20:48 -05:00
Navin Karkera
f79bebceeb feat: add subsection component
refactor: update publish modal to handle subsections and units

refactor: rename current section state and handlers

refactor: generalize edit title for section, subsection and unit

feat: generalize delete modal

feat: generalize publish modal

refactor: use currentSection and currentSubsection to improve delete item

feat: generalize duplication functionality

feat: generalize add new item for sections and subsections

test: fix subsection tests

fix: lint issues and test arguments

test: fix card header, delete and publish modal tests

fix: invalid use of delete subsection query for unit

refactor: use current section for highlights modal

feat: add auto scroll to subsection and improve scroll behaviour

fix: jsdoc types
2023-12-20 10:20:48 -05:00
Stephannie Jimenez
91ba00346c feat: add auto scroll to new sections when created
fix: rename util function and remove unused eslint comment

fix: fix tests by mocking scrollIntoView function

test: add assertion for checking call to mock function
2023-12-20 10:20:48 -05:00
Moncef Abboud
7286b21f5a feat: add Section Configure 2023-12-20 10:20:48 -05:00
Navin Karkera
134b75568a feat: section list and new section button
Also refactor api and hooks

fix: publish button behaviour and card header tests

fix: warning in highlights and publish modal test

fix: courseoutline tests

test: add test for new section functionality

fix(lint): lint issues

refactor: remove unnecessary css in CardHeader

refactor: rename emptyPlaceholder test file

refactor: replace ternary operator with 'and' condition

refactor: add black color to expand/collapse button

refactor: display only changed subsection and units in publish modal

refactor: update messages and css

refactor: wrap urls in function call

refactor: fix jsdoc types

refactor: use helmet for document title
2023-12-20 10:20:48 -05:00
vladislavkeblysh
59071424b3 feat: course outline - sections list
* feat: [2u-259] add components

* feat: [2u-259] fix sidebar

* feat: [2u-259] add tests, fix links

* feat: [2u-259] fix messages

* feat: [2u-159] fix reducer and sidebar

* feat: [2u-259] fix reducer

* feat: [2u-259] remove warning from selectors

* feat: [2u-259] remove indents

---------

Co-authored-by: Vladislav Keblysh <vladislavkeblysh@Vladislavs-MacBook-Pro.local>

feat: Course Outline  - Sections list (#59)

* feat: [2u-336] add tests

* feat: [2u-271] fix button

* feat: [2u-336] add component, refactor header

* fix: [2u-342] fix translates and indents

* fix: [2u-342] fix constants and expand block

* feat: [2u-336] remove new section from menu

---------

Co-authored-by: Vladislav Keblysh <vladislavkeblysh@Vladislavs-MacBook-Pro.local>

feat: Course outline - Content empty (#72)

* feat: [2u-324] add component

* feat: [2u-324] add translates

* feat: [2u-324] update tests

* feat: [2u-324] update branch

* fix: [2u-324] fixed empty handler

feat: Course outline - Section Publish (#61)

* feat: [2u-354] add publish modal, api and update tests

* feat: [2u-354] refactor modal

* fix: [2u-354] removed comments

* fix: [2u-354] fix indents

* fix: [2u-354] removed translates duplicates

* fix: [2u-354] rename handlers

feat: Course outline - Update section card (#71)

* feat: [2u-615] update section card

* fix: [2u-615] fix handler names

* fix: [2u-615] fix indents

* fix: [2u-615] add empty handler

* fix: [2u-615] fix data test id name

* fix: [2u-615] fix styles

fix: [2u-696] add saving processing for higlights and enable highlights (#78)

feat: Course outline - Section Edit (#70)

* feat: [2u-336] add tests

* feat: [2u-271] fix button

* feat: [2u-336] add component, refactor header

* feat: [2u-342] add modal

* fix: [2u-342] fix translates and indents

* feat: [2u-342] add modal

* feat: [2u-342] add api

* feat: [2u-342] add tests and translates

* feat: [2u-342] fix indents

* fix: [2u-342] fix indents, variant and utils

* feat: [2u-342] fixed slice, thunks, hooks

* feat: [2u-354] add publish modal, api and update tests

* feat: [2u-615] update section card

* feat: [2u-348] add api, handlers, tests

* feat: [2u-348] add description for api

* fix: [2u-348] fix useEscapeClick

* fix: [2u-348] remove useEffect from CardHeader

* fix: [2u-348] fixed handlers and tests

* fix: [2u-348] fixed handlers and tests

---------

Co-authored-by: Vladislav Keblysh <vladislavkeblysh@Vladislavs-MacBook-Pro.local>

feat: Course outline - Section Delete (#74)

* feat: [2u-336] add tests

* feat: [2u-271] fix button

* feat: [2u-336] add component, refactor header

* feat: [2u-342] add modal

* fix: [2u-342] fix translates and indents

* feat: [2u-342] add modal

* feat: [2u-342] add api

* feat: [2u-342] add tests and translates

* feat: [2u-342] fix indents

* fix: [2u-342] fix indents, variant and utils

* feat: [2u-342] fixed slice, thunks, hooks

* feat: [2u-354] add publish modal, api and update tests

* feat: [2u-615] update section card

* feat: [2u-348] add api, handlers, tests

* feat: [2u-510] add delete api, add delete modal

* fix: [2u-510] fixed tests

---------

Co-authored-by: Vladislav Keblysh <vladislavkeblysh@Vladislavs-MacBook-Pro.local>

feat: Course outline - Section duplicate (#88)

* feat: [2u-336] add tests

* feat: [2u-271] fix button

* feat: [2u-336] add component, refactor header

* feat: [2u-342] add modal

* fix: [2u-342] fix translates and indents

* feat: [2u-342] add modal

* feat: [2u-342] add api

* feat: [2u-342] add tests and translates

* feat: [2u-342] fix indents

* fix: [2u-342] fix indents, variant and utils

* feat: [2u-342] fixed slice, thunks, hooks

* feat: [2u-354] add publish modal, api and update tests

* feat: [2u-615] update section card

* feat: [2u-348] add api, handlers, tests

* feat: [2u-510] add delete api, add delete modal

* feat: [2u-360] add api

* feat: [2u-360] add slice

* feat: [2u-360] add tests

* fix: [2u-360] fixed tests

---------

Co-authored-by: Vladislav Keblysh <vladislavkeblysh@Vladislavs-MacBook-Pro.local>

fix: Course outline - Highlights links (#89)

* fix: fixed doc urls

* fix: fixed components

feat: Course outline - Collapse all sections (#75)

* feat: added collapse all section logic

* fix: fixed tests

fix: final revision commits

fix: increase code coverage on the page
2023-12-20 10:20:48 -05:00
renovate[bot]
f938d08361 fix(deps): update dependency @edx/frontend-lib-content-components to v1.177.7 (#757)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-19 14:25:06 -05:00
kenclary
47a3fd6836 Merge pull request #443 from openedx/kenclary/plugins
fix: re-enable private plugins, with newer version of public plugin repo
2023-12-19 13:09:13 -05:00
Ken Clary
82f6d7d3ca fix: re-enable private plugins, with newer version of public plugin repo 2023-12-19 12:28:57 -05:00
Jorg Are
f78e8a5671 fix: bump frontend-component-ai-translations-edx version (#756) 2023-12-19 18:08:55 +01:00
Kristin Aoki
4c7faad987 feat: break up load api to tab specific (#740) 2023-12-19 09:10:05 -05:00
Chris Chávez
bf46008878 style: UX Refinements on taxonomy pages [FC-0036] (#723)
This change makes the following updates to the UX of the taxonomy pages:

* On the taxonomies list, display the full name of taxonomies in a tooltip if it's longer than what's displayed
* On the taxonomy detail page, please change the title of the "Value" column to "Tag name"
* On taxonomy detail page, remove the "child tags" column and put it in parentheses instead
* Update tags count color
* Several minor issues brought up here: https://github.com/openedx/modular-learning/issues/105#issuecomment-1829412705. 
* Fix issue with scroll position not being reset on navigation
2023-12-19 09:44:44 +05:30
Rômulo Penido
a37d13f788 feat: add download template button to taxonomy list [FC-0036] (#674)
This commit adds a new button in the Taxonomy List to allow users to download a sample taxonomy template in the format used to import taxonomies.
2023-12-19 09:31:48 +05:30
Kristin Aoki
c68b2e3b06 Revert "chore(deps): update dependency @edx/frontend-build to v13.0.14 (#695)" (#753)
This reverts commit cb8bf2cd89.
2023-12-18 12:53:50 -05:00
dependabot[bot]
613220441f build(deps): bump sharp from 0.32.1 to 0.32.6 in /www (#441)
Bumps [sharp](https://github.com/lovell/sharp) from 0.32.1 to 0.32.6.
- [Release notes](https://github.com/lovell/sharp/releases)
- [Changelog](https://github.com/lovell/sharp/blob/main/docs/changelog.md)
- [Commits](https://github.com/lovell/sharp/compare/v0.32.1...v0.32.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-18 09:56:26 -05:00
renovate[bot]
cb8bf2cd89 chore(deps): update dependency @edx/frontend-build to v13.0.14 (#695)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-18 09:55:30 -05:00
renovate[bot]
089d8a8f79 fix(deps): update dependency @edx/frontend-component-footer to v12.6.1 (#688)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-18 09:47:00 -05:00
dependabot[bot]
57937995e2 build(deps): bump @babel/traverse from 7.21.5 to 7.23.6 in /www (#440)
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.21.5 to 7.23.6.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.6/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-18 09:37:57 -05:00
renovate[bot]
de9072d506 fix(deps): update dependency react-datepicker to v4.24.0 (#726)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-18 09:33:47 -05:00
dependabot[bot]
60ccf0fb53 build(deps): bump @babel/traverse from 7.22.5 to 7.23.6 (#439)
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.22.5 to 7.23.6.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.6/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-18 09:28:08 -05:00
renovate[bot]
279f8f2a6c fix(deps): update dependency react-textarea-autosize to v8.5.3 (#751)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-18 09:10:25 -05:00
Yusuf Musleh
7a4c9a36b6 feat: Search Content Tags (#737)
This change adds the ability to search content tags in the content tags
drawer, in order to filter tags. This change also refactors the way data
is loaded from the server, handling pre-loaded data and pagination.
2023-12-18 11:16:22 +05:30
Kristin Aoki
476f779e76 fix: files page timeout (#749) 2023-12-15 16:55:24 -05:00
Raymond Zhou
75eb0c307e fix: datatable state persistence issues (#746) 2023-12-15 14:52:59 -05:00
Jorg Are
da5d64ad9e fix: update transcript settings default logic (#745)
* fix: update transcript settings default logic

* fix: remove extra state logic
2023-12-15 10:52:12 -05:00
Peter Kulko
ad8fe53348 chore: added start:with-theme npm script (#747) 2023-12-15 10:15:04 +02:00
Jesper Hodge
94725dfe3c Fix undo reverts and update flcc to working version (#748)
* Revert "Fix  tinymce editor problems (#743)"

This reverts commit e6ce05571f.

* chore: update flcc to working version

* chore: update flcc to version that disables plugins
2023-12-14 15:30:05 -05:00
Jesper Hodge
287cc23ee7 fix: disable a11ychecker and powerpaste plugins (#437) 2023-12-14 15:09:04 -05:00
Jesper Hodge
56ffc495dd chore: disable tinymce plugins (#436) 2023-12-14 14:55:36 -05:00
Jesper Hodge
fbd3d8506f fix: editor container can scroll again (#435)
This is a fix to a problem where some css prevented the editors from scrolling.
2023-12-14 11:53:26 -05:00
kenclary
4483214de1 Merge pull request #434 from openedx/revert-432-kenclary/plugins
Revert "fix: disable paid plugins, to test prod issue in stage"
2023-12-13 10:46:40 -05:00
kenclary
aa17203e07 Revert "fix: disable paid plugins, to test prod issue in stage" 2023-12-13 10:39:37 -05:00
Jesper Hodge
e6ce05571f Fix tinymce editor problems (#743)
Internal issue: https://2u-internal.atlassian.net/servicedesk/customer/portal/9/CR-6328?created=true

Reverted 6 merged PRs due to problems.

scroll was not working on editors
potential problems with editor content loading

------------------------------------------------------


* Revert "fix(deps): update dependency @edx/frontend-lib-content-components to v1.177.4 (#742)"

This reverts commit cc40e9d6cb.

* Revert "feat: add escalation email field for LTI-based proctoring providers (#736)"

This reverts commit 0f483dc4e1.

* Revert "fix: video downloads (#728)"

This reverts commit c5abd21569.

* Revert "fix: import api to chunk file (#734)"

This reverts commit 6f7a992847.

* Revert "feat: Taxonomy delete dialog (#684)"

This reverts commit 1eff489158.

* Revert "fix(deps): update dependency @edx/frontend-lib-content-components to v1.177.1 (#727)"

This reverts commit dcabb77218.
2023-12-12 18:23:26 -05:00
renovate[bot]
cc40e9d6cb fix(deps): update dependency @edx/frontend-lib-content-components to v1.177.4 (#742)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-12 16:14:03 -05:00
Jesper Hodge
57042c90bf Revert "fix: get library blocks editing to work locally (#431)" (#433)
This reverts commit fd3ed5d146.
2023-12-12 15:57:03 -05:00
kenclary
6dab3a1cea Merge pull request #432 from openedx/kenclary/plugins
fix: disable paid plugins, to test prod issue in stage
2023-12-12 15:30:44 -05:00
Ken Clary
7c7b36b402 fix: disable paid plugins, to test prod issue in stage 2023-12-12 15:22:15 -05:00
Jesper Hodge
fd3ed5d146 fix: get library blocks editing to work locally (#431)
* fix: get library blocks editing to work locally

* fix: tests
2023-12-12 14:34:27 -05:00
Michael Roytman
0f483dc4e1 feat: add escalation email field for LTI-based proctoring providers (#736)
This commit adds an escalation email field for LTI-based proctoring providers to the Proctoring modal on the Pages & Resources page. This field behaves identically to the Proctortrack escalation email.
2023-12-12 14:28:23 -05:00
Kristin Aoki
c5abd21569 fix: video downloads (#728) 2023-12-12 11:00:40 -05:00
Kristin Aoki
6f7a992847 fix: import api to chunk file (#734) 2023-12-12 10:28:33 -05:00
Chris Chávez
1eff489158 feat: Taxonomy delete dialog (#684)
This adds:
    New submenu 'Delete' on the Taxonomy card menu
    Delete Dialog with the functionality to delete a Taxonomy
    Show a Toast after delete the Taxonomy
    Enable export for System defined Taxonomies
2023-12-12 17:54:39 +05:30
renovate[bot]
dcabb77218 fix(deps): update dependency @edx/frontend-lib-content-components to v1.177.1 (#727)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-11 13:11:53 -05:00
kenclary
1137c88a02 Merge pull request #428 from openedx/kenclary/plugins
fix: misssing part of paid plugin configuration
2023-12-11 12:07:25 -05:00
Ken Clary
b0ca07d801 fix: misssing part of paid plugin configuration 2023-12-11 11:46:57 -05:00
Jorg Are
67cda575a5 fix: bump ai translations component (#739) 2023-12-11 09:16:40 -05:00
Kristin Aoki
195c9e416c fix: grading segment number ranges (#729) 2023-12-08 13:26:36 -05:00
Kristin Aoki
5db6b2049f fix: wrong min count alert showing (#730) 2023-12-08 13:21:36 -05:00
Yusuf Musleh
c9b73a5008 feat: Add content tags tree state + editing (#704)
This commit adds the add/remove functionality of content tags where the
state is stored and changes are updated in the backend through the API.
Changes are reflected in the UI automatically.
2023-12-08 13:55:57 +05:30
Kristin Aoki
56ad86ee60 feat: update usage metrics to be a hyperlink (#717) 2023-12-07 12:30:15 -05:00
Navin Karkera
04c14274fd feat: course outline page (#694)
* feat: Course outline Top level page (#36)

* feat: [2u-259] add components

* feat: [2u-259] fix sidebar

* feat: [2u-259] add tests, fix links

* feat: [2u-259] fix messages

* feat: [2u-159] fix reducer and sidebar

* feat: [2u-259] fix reducer

* feat: [2u-259] remove warning from selectors

* feat: [2u-259] remove indents

---------

Co-authored-by: Vladislav Keblysh <vladislavkeblysh@Vladislavs-MacBook-Pro.local>

feat: Course outline Status Bar (#50)

* feat: [2u-259] add components

* feat: [2u-259] fix sidebar

* feat: [2u-259] add tests, fix links

* feat: [2u-259] fix messages

* feat: [2u-159] fix reducer and sidebar

* feat: add checklist

* feat: [2u-259] fix reducer

* feat: [2u-259] remove warning from selectors

* feat: [2u-259] remove indents

* feat: [2u-259] add api, enable modal

* feat: [2u-259] add tests

* feat: [2u-259] add translates

* feat: [2u-271] fix transalates

* feat: [2u-281] fix isQuery pending, utils, hooks

* feat: [2u-281] fix useScrollToHashElement

* feat: [2u-271] fix imports

---------

Co-authored-by: Vladislav Keblysh <vladislavkeblysh@Vladislavs-MacBook-Pro.local>

feat: Course Outline Reindex (#55)

* feat: [2u-277] add alerts

* feat: [2u-277] add translates

* feat: [2u-277] fix tests

* fix: [2u-277] fix slice and hook

---------

Co-authored-by: Vladislav Keblysh <vladislavkeblysh@Vladislavs-MacBook-Pro.local>

fix: Course outline tests (#56)

* fix: fixed course outline status bar tests

* fix: fixed course outline status bar tests

* fix: fixed course outline enable highlights modal tests

* fix: enable modal tests

fix: increase code coverage on the page

* refactor: improve course outline page

feat: lms live link

chore: update outline link

fix: course outline link

refactor: remove unnecessary css and rename test file

refactor: remove unnecessary css from outlineSidebar

test: make use of message variable instead of hardcoded text

refactor: remove unnecessary h5 class

test: use test id for detecting component

refactor: update course outline url and some default messages

---------

Co-authored-by: vladislavkeblysh <138868841+vladislavkeblysh@users.noreply.github.com>
2023-12-06 10:06:29 -05:00
Jorg Are
bebbc1535b feat: add ai translations component to transcript settings (#722) 2023-12-05 16:22:46 -05:00
Artur Gaspar
1c9771b332 feat: video gallery thumbnail fallback (#412) 2023-12-04 09:58:40 -05:00
Artur Gaspar
1ddaf9a662 fix: video editor and uploader layout fixes (#410)
* fix: video upload page layout fixes

* fix: video editor thumbnail fallback icon colour and size

* fix: video uploader close button go back instead of closing app

Change the video uploader close button to always go back in navigation history,
and change the gallery to replace its location with the video uploader's when
automatically loading it due to an empty video list, so that when the uploader
goes back in the history, it goes to what was before the gallery.

* fix: video editor spinners vertical alignment

The Editor component uses the pgn__modal-fullscreen class to be fullscreen,
but it is not structured like a Paragon FullscreenModal and the fullscreen
positioning style is not applied correctly, particularly in the case where
the content is smaller than the body - a vertically centred component will
be centred to the content size, not to the screen.

Here we directly apply the style that would have applied to the relevant
elements of a Paragon FullscreenModal.

* fix: use trailingElement for video uploader input button

Also styles the button so it looks the same on hover/active.
2023-12-04 09:58:17 -05:00
Artur Gaspar
2aeb094315 fix: video gallery design fixes (#407) 2023-12-04 09:35:30 -05:00
renovate[bot]
1636226572 fix(deps): update dependency @edx/frontend-lib-content-components to v1.176.4 (#720)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-01 12:33:36 -05:00
Dmytro
ed051c3543 fix: default display of Show Answer and Show reset option (#403)
Hardcoding values for showAnswer and showResetButton
in initialState leads to incorrect selection of additional
states specified in Advanced settings.
2023-12-01 09:26:12 -05:00
Dmytro
60439d5be6 fix: displaying the correct default randomization value (#413) 2023-11-30 16:33:25 -05:00
Maria Grimaldi
2fbcfc03dd fix: remove unnecessary course-v1 from courseId string (#687) 2023-11-30 15:56:38 -05:00
ABBOUD Moncef
8928d35f17 fix: make filter dropdown closable by clicking outside + revert to single-value video filter (#414) 2023-11-30 14:43:12 -05:00
Ihor Romaniuk
bad763596c fix: video thumbnail availability (#421) 2023-11-30 14:34:19 -05:00
Kristin Aoki
ac1fc43250 fix: visibility of transcript dropdowns (#719) 2023-11-30 13:21:34 -05:00
Kristin Aoki
a2dceac62f feat: add notification of transcription error (#715) 2023-11-28 16:55:00 -05:00
Kristin Aoki
2402769d9d fix: sort of boolean columns (#705) 2023-11-28 13:13:54 -05:00
Feanil Patel
7030d6c1ba build: Updating workflow commitlint.yml.
The .github/workflows/commitlint.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-11-27 12:18:56 -05:00
renovate[bot]
1edc7d3329 fix(deps): update dependency @edx/frontend-lib-content-components to v1.176.0 (#709)
* fix(deps): update dependency @edx/frontend-lib-content-components to v1.176.0

* fix: mock frontend-components-tinymce-advanced-plugins for jest

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Ken Clary <kclary@edx.org>
2023-11-23 15:34:29 -05:00
Braden MacDonald
352ef35ac2 feat: display all child tags in the "bare bones" taxonomy detail page (#703)
Also includes:
- feat: set <title> on taxonomy list page and taxonomy detail page
- fix: display all taxonomies on the list page, even if > 10
- refactor: separate out loading spinner component
2023-11-23 01:44:17 +05:30
Kristin Aoki
f9b008e8e8 feat: original fetch to includes usage metrics (#701) 2023-11-22 13:54:13 -05:00
Kristin Aoki
251259e4bd feat: add new libray button (#710) 2023-11-22 13:42:37 -05:00
kenclary
c0bc54a664 Merge pull request #420 from openedx/kenclary/plugins
feat: use plugins repo, and enable accessibility checker and powerpaste
2023-11-22 10:50:56 -05:00
Adolfo R. Brandes
a622f8e86e fix: Fix data API URL handling
All configuration calls must handled asynchronously, otherwise they risk
failure in runtime configuration scenarios.
2023-11-21 16:57:04 -03:00
Ken Clary
5342f164a2 feat: use plugins repo, and enable accessibility checker and powerpaste 2023-11-21 14:27:10 -05:00
Rômulo Penido
02cdccc77c feat: bare bones taxonomy detail page [FC-0036] (#655)
* feat: System-defined tooltip added

* feat: Taxonomy card menu added. Export menu item added

* feat: Modal for export taxonomy

* feat: Connect with export API

* test: Tests for API and selectors

* feat: Use windows.location.href to call the export endpoint

* test: ExportModal.test added

* style: Delete unnecesary code

* docs: README updated with taxonomy feature

* style: TaxonomyCard updated to a better code style

* style: injectIntl replaced by useIntl on taxonomy pages and components

* refactor: Move and rename taxonomy UI components to match 0002 ADR

* refactor: Move api to data to match with 0002 ADR

* test: Refactor ExportModal tests

* chore: Fix validations

* chore: Lint

* refactor: Moving hooks to apiHooks

* feat: add taxonomy detail page

* fix: address nits in PR review

* refactor: move data/selectors to data/apiHooks

and fix tests to mock useQuery.

* fix: address nits in PR review

* fix: replace taxonomy menu ModalPopup with Dropdown menu

Avoids clicking through to the card when using the menu button to hide
a card's menu.

* fix: change taxonomy URLs

* /taxonomy-list is now /taxonomies, and there's a temporary redirect
* /taxonomy-list/🆔 is now /taxonomy/🆔

---------

Co-authored-by: Christofer <christofer@opencraft.com>
Co-authored-by: XnpioChV <xnpiochv@gmail.com>
Co-authored-by: Christofer Chavez <christofer@example.com>
Co-authored-by: Jillian Vogel <jill@opencraft.com>
Co-authored-by: Braden MacDonald <braden@opencraft.com>
2023-11-20 17:15:31 -03:00
Yusuf Musleh
375006deb1 feat: Implement Content Tags Drawer
This implements a side drawer widget for content taxonomy tags.
It includes displaying the object's tags, along with their
lineage (ancestor tags) data. It also implements the listing the
available taxonomy tags (including nesting ones) to select from
to apply to this unit.

Note: The editing of tags (adding/removing) will be added in a future
PR.

* feat: Add initial UnitTaxonomyTagsDrawer widget
* feat: Add fetching unit taxonomy tags from backend
* feat: Add fetching/group tags with taxonomies
* feat: Add fetch Unit data and display name
* feat: Add Taxonomy Tags dropdown selector
* feat: Add TagBubble for tag styling
* chore: Add distinct keys to elements + remove logs
* feat: Add close drawer with ESC- keypress
* feat: Make dropdown selectors keyboard accessible
* chore: Fix issues causing validation to fail
* test: Add coverage tests for UnitTaxonomyDrawer
* feat: Incorporate tags lineage data from API
* refactor: Remove/replace deprecated injectIntl
* test: Remove redux store related code + fix warnings
* feat: Use <Loading /> instead of loading string
* docs: Add docs string to TaxonomyTagsCollapsible
* feat: Use <Spinner/> to allow mutiple loading to show
* feat: Rename UnitTaxonomyTagDrawer -> ContentTagsDrawer
* feat: Add ContentTagsTree component to render Tags
* feat: Only fetch tags when dropdowns are opened
* refactor: Simply dropdown close/open states
* feat: Use built in class styles instead of custom
* feat: Replace hardcoded values with scss variables
* refactor: follow existing structure for reactQuery/APIs
* feat: Change tag bubble outline color
* feat: Add TagOutlineIcon for implicit tags
* feat: Make aria label internationalized
* feat: Replace custom styles with builtin classes
* fix: Fix bug with closing drawer
* refactor: Simplify content tags fetching code
* refactor: Simplify getTaxonomyListApiUrl
2023-11-20 16:56:46 -03:00
Kristin Aoki
9b053de0b7 fix: filter overwritten by sort (#702) 2023-11-20 14:06:36 -05:00
Kristin Aoki
a62c53eb00 fix: pagination style (#697) 2023-11-20 09:18:36 -05:00
Kristin Aoki
08d895b2e0 fix: list more info menu styles (#696) 2023-11-17 09:48:32 -05:00
Kristin Aoki
eb3ee3a6b2 fix: transcript tab layout (#686)
* fix: transcript tab layout

* fix: console warnings for missing config values
2023-11-17 09:48:13 -05:00
Kristin Aoki
af0124d4e6 fix: general page layout and colors (#693) 2023-11-16 18:05:50 -05:00
Kristin Aoki
3d37bc056d fix: page specific messages (#691) 2023-11-16 16:40:57 -05:00
dependabot[bot]
a25bc0670e chore(deps-dev): bump semver from 5.7.1 to 5.7.2 (#665)
Bumps [semver](https://github.com/npm/node-semver) from 5.7.1 to 5.7.2.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v5.7.1...v5.7.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-16 14:02:38 -05:00
dependabot[bot]
0f4662265a chore(deps): bump tinymce from 5.10.5 to 5.10.9 (#685)
Bumps [tinymce](https://github.com/tinymce/tinymce/tree/HEAD/modules/tinymce) from 5.10.5 to 5.10.9.
- [Changelog](https://github.com/tinymce/tinymce/blob/5.10.9/modules/tinymce/CHANGELOG.md)
- [Commits](https://github.com/tinymce/tinymce/commits/5.10.9/modules/tinymce)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-16 13:52:56 -05:00
Kristin Aoki
79bb38a098 fix: use styles from frontend-content-header (#690) 2023-11-16 13:38:59 -05:00
Jesper Hodge
ed1c83fe7f chore: update decode-uri-component (#692) 2023-11-16 13:33:51 -05:00
dependabot[bot]
b0bd80d8d1 build(deps): bump decode-uri-component from 0.2.0 to 0.2.2 (#401)
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-11-16 13:02:56 -05:00
renovate[bot]
9aef1a88ba fix(deps): update dependency @edx/frontend-component-header to v4.10.1 (#689)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-16 12:59:43 -05:00
renovate[bot]
0f80e27978 fix(deps): update dependency @reduxjs/toolkit to v1.9.7 (#679)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-16 12:51:52 -05:00
dependabot[bot]
c5fc16b77a build(deps): bump @xmldom/xmldom from 0.7.5 to 0.7.8 (#376)
Bumps [@xmldom/xmldom](https://github.com/xmldom/xmldom) from 0.7.5 to 0.7.8.
- [Release notes](https://github.com/xmldom/xmldom/releases)
- [Changelog](https://github.com/xmldom/xmldom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/xmldom/xmldom/compare/0.7.5...0.7.8)

---
updated-dependencies:
- dependency-name: "@xmldom/xmldom"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-16 12:13:57 -05:00
dependabot[bot]
d5f0691fc3 chore(deps): bump @babel/traverse from 7.22.17 to 7.23.2 (#664)
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.22.17 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-16 10:53:29 -05:00
Emad Rad
91019b4a51 feat: Persian language support added (#553)
* fix: corrected typos

justify-contnt-center -> justify-content-center
Visiblity -> Visibility
Wraper -> Wrapper
closeAssetinfo -> closeAssetInfo
RestictDatesInput -> RestrictDatesInput
isOnSmallcreen -> isOnSmallScreen
Repsonse -> Response
configuation -> configuration
seconary -> secondary
comparesion -> comparison

* feat: Persian language (fa_IR) added

* refactor: better variable name for languages

* chore: sort languages alphabetically
2023-11-16 09:01:08 +05:30
renovate[bot]
2804f38d4f chore(deps): update dependency axios-mock-adapter to v1.22.0 (#678)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-15 16:48:29 -05:00
renovate[bot]
416ac4fbdc chore(deps): update dependency @edx/frontend-build to v13.0.5 (#676)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-15 16:48:15 -05:00
renovate[bot]
14e3c258fb fix(deps): update dependency @edx/brand to v1.2.3 (#667)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-15 16:47:48 -05:00
Kristin Aoki
ce9db575a6 fix: table search filter (#683) 2023-11-14 13:21:11 -05:00
Chris Chávez
1ee80b68ec feat: Taxonomy export menu [FC-0036] (#645)
* feat: System-defined tooltip added
* feat: Taxonomy card menu added. Export menu item added
* feat: Modal for export taxonomy
* feat: Connect with export API
* test: Tests for API and selectors
* feat: Use windows.location.href to call the export endpoint
* test: ExportModal.test added
* style: Delete unnecessary code
* docs: README updated with taxonomy feature
* style: TaxonomyCard updated to a better code style
* style: injectIntl replaced by useIntl on taxonomy pages and components
* refactor: Move and rename taxonomy UI components to match 0002 ADR
* refactor: Move api to data to match with 0002 ADR
* test: Refactor ExportModal tests
* chore: Fix validations
* chore: Lint
* refactor: Moving hooks to apiHooks
* style: Nit on return null

---------

Co-authored-by: Rômulo Penido <romulo@dash.dev.br>
Co-authored-by: Christofer Chavez <christofer@example.com>
2023-11-14 13:08:37 -05:00
Kristin Aoki
7c7ea1fbc2 fix: active transcript preference not loading (#682) 2023-11-14 10:43:01 -05:00
Kristin Aoki
3378c8e170 fix: combine filter and sort into one modal (#680) 2023-11-13 15:22:44 -05:00
Kristin Aoki
2fbb490cbb fix: total file count update on add and delete (#681) 2023-11-13 14:46:31 -05:00
Zachary Hancock
e41efba0cd feat: opt out is not supported by lti proctoring (#673)
This toggle does nothing if an LTI tool is selected. We should hide it in that case.
2023-11-13 09:14:54 -05:00
Zachary Hancock
7c7b3cdc07 feat: remove old/duplicate proctoring component (#671) 2023-11-09 08:55:25 -05:00
Kristin Aoki
78eb512836 refactor: files-and-videos folder (#672) 2023-11-08 15:54:47 -05:00
Kristin Aoki
3dac6aa188 fix: modal exit redirect (#659) 2023-11-07 16:09:25 -05:00
renovate[bot]
4a3d1a1787 fix(deps): update dependency @edx/frontend-lib-content-components to v1.175.1 (#663)
* fix(deps): update dependency @edx/frontend-lib-content-components to v1.175.1

* fix: upgrade paragon

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: KristinAoki <kaoki@2u.com>
2023-11-07 15:43:44 -05:00
renovate[bot]
2cfde7d3f4 fix(deps): update dependency @edx/frontend-component-header to v4.9.3 (#651)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-07 14:47:50 -05:00
Kristin Aoki
05e90b59d2 fix: fidelity typo in preference api (#662) 2023-11-07 14:05:08 -05:00
Kristin Aoki
02a683f09a fix: end date error when certificate row not shown (#668) 2023-11-07 11:31:21 -05:00
renovate[bot]
f61f7429bd chore(deps): update dependency @edx/frontend-build to v13.0.4 (#641)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-06 15:37:34 -05:00
renovate[bot]
09f908b019 fix(deps): update dependency @edx/frontend-component-footer to v12.5.1 (#650)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-06 15:25:11 -05:00
renovate[bot]
d5cc56756e fix(deps): update dependency react-transition-group to v4.4.5 (#647)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-06 13:26:16 -05:00
renovate[bot]
77a355ee8d chore(deps): update dependency @edx/browserslist-config to v1.2.0 (#649)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-06 09:55:07 -05:00
renovate[bot]
7bcce0b9d9 fix(deps): update font awesome (#648)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-06 09:43:19 -05:00
renovate[bot]
e1602258dc chore(deps): update dependency glob to v7.2.3 (#643)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-06 09:40:08 -05:00
renovate[bot]
78ef3c3f37 fix(deps): update dependency moment to v2.29.4 [security] (#630)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-06 09:35:33 -05:00
renovate[bot]
890d664746 chore(deps): update dependency @testing-library/jest-dom to v5.17.0 (#653)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-06 09:18:13 -05:00
Kristin Aoki
a28338df30 feat: add video page (#640) 2023-11-06 08:51:21 -05:00
Jeremy Ristau
fc8070025b Merge pull request #415 from Mashal-m/mashal-m/update-README
refactor: updated README file to reflect template changes
2023-10-31 08:39:15 -04:00
Kristin Aoki
3aa9088309 fix: upgrade paragon (#416) 2023-10-30 11:39:09 -04:00
Jesper Hodge
221fcf77dc feat: change filter status text (#657)
Changed the filter status text on the files and uploads table to display also the number of files, even when a filter is applied.

https://2u-internal.atlassian.net/browse/TNL-11086 (internal ticket)

I just copied most of paragon's FilterStatus component, made some adjustments, and then overrode the default component.
2023-10-27 10:25:51 -04:00
Syed Ali Abbas Zaidi
42614b8d8e chore: bump frontend-platform (#409) 2023-10-27 09:30:51 -04:00
mashal-m
b3811b8f4d refactor: updated README file to reflect template changes 2023-10-27 12:07:46 +05:00
Stanislav
378b0e93eb fix: Missed favicon in Safari (#633)
Co-authored-by: Stanislav Lunyachek <lunyachek@MacBook-Pro-M1.local>
2023-10-25 14:07:26 -04:00
sundasnoreen12
a69711942b fix: fixed issue of unable to call handle submit function on button click (#656) 2023-10-25 22:58:46 +05:00
Braden MacDonald
0679022f7a docs: some updates to the readme (#625) 2023-10-25 10:29:51 -04:00
Syed Ali Abbas Zaidi
d497b01c45 feat: upgrade react router to v6 (#519)
## Ticket
[React Router Upgrade to v6](https://github.com/openedx/platform-roadmap/issues/276).

## Description
This PR upgrades React Router from `v5` to `v6`.
2023-10-20 16:52:23 -04:00
Jesper Hodge
682c3b64b2 chore: adjust renovate config (#637) 2023-10-20 13:53:42 -04:00
Feanil Patel
9715429ed0 chore: Update to the new version of brand-openedx in the new scope. (#646)
Part of https://github.com/openedx/axim-engineering/issues/23

This updates the `@edx/brand` alias to point to the `brand-openedx` package at
the `openedx` scope. This does not impact imports because this package is used
via an alias.
2023-10-20 13:29:49 -04:00
Chris Chávez
ad4d9b9c63 Taxonomy list page [FC-0036] (#622) 2023-10-20 11:55:20 -04:00
Jesper Hodge
85a19f7971 chore: change files page title (#639)
Changed "Files & Uploads" page title to just "Files"
2023-10-19 11:21:46 -04:00
Peter Kulko
6705f638c0 fix: fixed sidebar margin top (#73) (#593) 2023-10-18 13:42:44 -04:00
Jesper Hodge
618831f1eb fix: info modal and list view thumbnails (#636) 2023-10-17 12:17:03 -04:00
renovate[bot]
6287e8c01b fix(deps): update dependency @edx/frontend-lib-content-components to v1.175.0 (#631)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-17 12:05:34 -04:00
Jesper Hodge
beb035b3e1 fix file upload thumbnails (#629)
Internal issue: https://2u-internal.atlassian.net/browse/TNL-11085

File upload gallery cards had distorted thumbnails. The goal is to fix this.
I centered the thumbnails instead of stretching them. I had to change the card layout a bit to do that, so in order to make everything look fine, I worked a bit on margins and paddings and font-size in order to bring this close to the figma mockups. It's not perfect because when you resize the browser window, the grid does some resizing that doesn't look as good as in figma, but I think it should be good enough for now.
2023-10-17 10:22:49 -04:00
Kristin Aoki
5c101b09d4 feat: update list view to be table (#628) 2023-10-16 14:58:28 -04:00
Jesper Hodge
7132136a91 chore: disable renovate automerge and add flcc rules (#624)
* chore: disable renovate automerge and add flcc rules

* chore: add dependency dashboard
2023-10-11 16:58:52 -04:00
Jesper Hodge
cfa4577b75 chore: add test change for flcc automerge (#408) 2023-10-11 13:58:42 -04:00
Muhammad Abdullah Waheed
03bf93ad13 feat: babel-plugin-react-intl to babel-plugin-formatjs migration (#621)
* feat: babel-plugin-react-intl to babel-plugin-formatjs migration

* fix: upgraded frontend-build to fix security issue
2023-10-11 11:38:36 -04:00
kenclary
2377eadcc0 Merge pull request #400 from abdullahwaheed/abdullahwaheed/react-intl-to-formatjs
feat: babel-plugin-react-intl to babel-plugin-formatjs migration
2023-10-11 11:38:30 -04:00
Navin Karkera
65859924c2 fix: await async saveSetting func to remove unwanted err msg (#610) 2023-10-11 10:42:43 -04:00
kenclary
b55b86cf56 Merge pull request #404 from open-craft/navin/fix-max-attempts-setting
fix: make max attempts setting fallback to default
2023-10-11 10:04:16 -04:00
Abdullah Waheed
71fd5fb1e0 fix: upgraded frontend-build to fix security issue 2023-10-11 18:44:01 +05:00
Abdullah Waheed
9ddcba2763 Merge branch 'main' of github.com:openedx/frontend-lib-content-components into abdullahwaheed/react-intl-to-formatjs 2023-10-11 18:43:34 +05:00
Bilal Qamar
97d0a1ce61 feat: update react & react-dom to v17 (#514)
* feat: update react & react-dom to v17

* refactor: updated package-lock

* refactor: updated failing tests

* refactor: updated FilesAndUploads test to resolve delay issue

* refactor: updated DiscussionSettings tests

* refactor: downgraded frontend-lib-content-components

* refactor: resolved lint issue

* refactor: bumped frontend-lib-content-components version

* refactor: updated CollapsibleStateWithAction test suit

* refactor: update FilesAndUploads test
2023-10-11 11:08:26 +05:00
Jeremy Ristau
a76c93c789 Merge pull request #361 from ghassanmas/fix-360
fix: resolve  #360 make style consistent across outlines
2023-10-10 14:28:38 -04:00
Navin Karkera
6889cd1e82 test: add test for initial attempts display value 2023-10-10 20:19:00 +05:30
Navin Karkera
35a2f3bb7f fix: use only null in state for empty value 2023-10-10 19:52:39 +05:30
Navin Karkera
e676616386 fix: snapshots 2023-10-10 12:53:11 +05:30
Navin Karkera
2209e5b963 fix: lint issues 2023-10-10 12:19:14 +05:30
Navin Karkera
82b770bdef refactor: improve hooks condition handling 2023-10-10 12:13:46 +05:30
Navin Karkera
398839d76c refactor: improve setting parser condition handling 2023-10-09 21:29:53 +05:30
Navin Karkera
5df26bf83b test: fix related test cases 2023-10-09 20:34:05 +05:30
Navin Karkera
c70679da54 fix: make max attempts setting fallback to default
The max attempts setting for a problem xblock should be set to null for
course default max attempt setting to take effect. This makes sure that
xblock setting is updated if course default is updated.
2023-10-06 20:35:53 +05:30
Abdullah Waheed
e474a6fc91 feat: babel-plugin-react-intl to babel-plugin-formatjs migration 2023-10-04 22:17:12 +05:00
German
3fe35344f0 feat: update copy for xpert summary card (#619) 2023-10-03 17:18:04 -03:00
edx-transifex-bot
bbca5a29b7 chore(i18n): update translations (#616)
Co-authored-by: Jenkins <sre+jenkins@edx.org>
2023-10-02 15:44:34 -04:00
Kristin Aoki
2a6a816baf feat: update footer and header to use frontend-component version (#618) 2023-10-02 15:06:33 -04:00
Kristin Aoki
564d724d5b feat: remove footer component (#397) 2023-10-02 10:29:37 -04:00
Mashal Malik
73f7d5d5f5 refactor: add @openedx in renovate automate configuration (#617) 2023-10-02 10:16:08 -04:00
Kristin Aoki
0871ce345a fix: studio home load screen (#615) 2023-09-29 14:29:31 -04:00
Kristin Aoki
01ddac380f fix: studio home UI bugs (#611) 2023-09-28 18:36:51 -04:00
Kristin Aoki
4840666664 fix: export download link prefix (#614) 2023-09-28 12:14:25 -04:00
Kristin Aoki
21e4ece669 fix: bump frontend-lib-content-components (#613) 2023-09-27 12:58:01 -04:00
Kristin Aoki
887a628c23 fix: export and import UI bugs (#612) 2023-09-27 12:10:45 -04:00
Kristin Aoki
a0089eb1be fix: typeahead sort and styling (#396) 2023-09-27 12:09:27 -04:00
Kyrylo Kholodenko
2ea876ae4f feat: implement import page (#587) 2023-09-25 12:07:08 -04:00
Kristin Aoki
c47c800cfa fix: advanced settings card alignment (#608) 2023-09-22 17:29:38 -04:00
Kristin Aoki
ef9633af35 fix: course updates UI bugs (#606)
* fix: change edit and delete buttons to icons

* fix: padding and button color

* fix: delete buttons and variant

* fix: date error icon color

* fix: page explanation text
2023-09-22 15:51:04 -04:00
Kristin Aoki
217b86e616 fix: missing header items (#607) 2023-09-22 14:56:14 -04:00
sundasnoreen12
37aabc4948 fix: update toggle state based on api response (#604)
* fix: update toggle state based on api response

* refactor: added statefulbutton instead of button

---------

Co-authored-by: SundasNoreen <sundas.noreen@arbisoft.com>
2023-09-22 16:58:49 +05:00
kenclary
eb320abfed Merge pull request #386 from open-craft/navin/partial-credit
fix: switch to advanced editor for partial credit support
2023-09-20 11:58:52 -04:00
ruzniaievdm
e099243437 feat: create Studio Home Page MFE (#589) 2023-09-19 10:04:43 -04:00
Kristin Aoki
6f238bdbe0 fix: bump frontend-lib-content-components (#602) 2023-09-15 14:02:18 -04:00
Kristin Aoki
773812c3e1 fix: block url conditional (#393) 2023-09-15 11:23:01 -04:00
Kristin Aoki
9eefc07832 fix: empty v2 library studio view (#394) 2023-09-15 09:05:51 -04:00
Kristin Aoki
bc25f9c21b fix: v2 libraries default open to advanced editor (#392) 2023-09-14 11:41:14 -04:00
kenclary
4cf99ab930 Merge pull request #388 from open-craft/farhaan/bb-7835-fix-styling
fix: Fix styling for components in dropzone
2023-09-14 11:37:47 -04:00
Kristin Aoki
77dfd0296c fix: bump frontend-lib-content-components (#601) 2023-09-14 09:42:04 -04:00
Kyrylo Kholodenko
1888993113 feat: implement export page (#586) 2023-09-14 09:07:24 -04:00
Farhaan Bukhsh
db8929d1a8 fix: Fix styling for components in dropzone
Signed-off-by: Farhaan Bukhsh <farhaan@opencraft.com>
2023-09-14 12:52:26 +05:30
Kristin Aoki
126e662d80 feat: remove replace video button for libs (#390) 2023-09-13 13:35:42 -04:00
Kristin Aoki
39aa5aa749 feat: update isLibrary check to include v2 libs (#389) 2023-09-13 13:13:18 -04:00
Kristin Aoki
73af4317f6 fix: name of blank problems (#391) 2023-09-13 10:55:28 -04:00
Kristin Aoki
fb28693854 fix: bump frontend-lib-content-components (#600) 2023-09-12 10:45:31 -04:00
Kristin Aoki
7f8c6f2d61 feat: update header to be keyboard accessible (#597) 2023-09-12 10:19:29 -04:00
Kristin Aoki
4f76b7c85e fix: sort items in typeahead dropdown (#387) 2023-09-12 09:48:43 -04:00
Syed Ali Abbas Zaidi
c44c72cec0 feat: upgrade react router to v6 (#280) 2023-09-12 09:04:42 -04:00
Navin Karkera
e3f5bbfe0c fix: switch to advanced editor for partial credit support
This commit reverts to advanced editor when partial_credit attribute is
added to multichoice, single select and numerical problems. Without this
change, the partial_credit attribute is removed from the problem on the
next edit.
2023-09-11 20:14:04 +02:00
Mohamed Akram
25e4e39953 fix: preformatted content being re-formatted (#376)
The issue had to do with how Firefox handles pasting newlines inside a <pre
contenteditable> tag (TinyMCE's editor works via contenteditable) and
fast-xml-parser's parsing. In Firefox, newlines are converted to <br> when
pasted, while Chrome preserves them. The parser by default trims spaces in text
nodes. In Firefox, the parser creates individual text nodes between the <br>
elements, and those have leading spaces in the example. In Chrome, there are no
<br> elements and the entire content is a single text node as-is. Setting
trimValues to false disables the trimming and resolves this issue in Firefox.

While investigating this, I noticed the builder also mishandles <br /> tags
emitted by the editor, converting them to <br></br>. The unpairedTags option in
the builder ensures they are output correctly as a single tag, and setting
suppressUnpairedNode to false ensures that single tag is <br/> rather than <br>
to remain XML compatible.

While trying to resolve this, I was looking into the paste plugin in TinyMCE.
It changes the behavior of pasting, making it more consistent between Chrome
and Firefox (i.e. both emit <br>) and is incorporated into TinyMCE 6 core.
Unfortunately, it seems to mangle pasting inside a <pre> tag by inserting
redundant nbsp characters (tinymce/tinymce#9017). TinyMCE 6 also outputs <br>
rather than <br /> - adding unpairedTags to the parser options is meant to
handle this, but it does not seem to behave entirely correct
(NaturalIntelligence/fast-xml-parser#609). These should be kept in mind if/when
upgrading to TinyMCE 6 (the different behaviors can be seen easily at
https://fiddle.tiny.cloud).
2023-09-11 10:47:04 -04:00
Kristin Aoki
15984473b4 fix: bump frontend-lib-content-components (#595) 2023-09-07 09:53:20 -04:00
ruzniaievdm
b03ecf1562 fix: reworked grading deadline (#584) 2023-09-07 09:18:08 -04:00
Kristin Aoki
9ebe187029 fix: undefined set selection for image modal (#384) 2023-09-06 16:48:21 -04:00
Kristin Aoki
fdc5916ada fix: course team UI bugs (#592) 2023-09-06 14:45:17 -04:00
Kristin Aoki
a54d351e9c fix: schedule and details UI bugs (#588) 2023-09-06 12:32:19 -04:00
Kristin Aoki
62cde57556 fix: grading page UI bugs (#591) 2023-09-06 11:20:12 -04:00
Kristin Aoki
2bd8037d7b feat: change head title depending on page (#582) 2023-09-06 11:02:16 -04:00
Kyrylo Kholodenko
a1793efcc0 feat: add help-urls (#585) 2023-09-05 14:17:39 -04:00
Kristin Aoki
ed2eed5110 feat: add file zip on download (#580) 2023-09-05 10:23:47 -04:00
Kristin Aoki
e50b8c7407 feat: add file size and usage metrics (#573) 2023-08-31 12:21:37 -04:00
vladislavkeblysh
ffae3bd868 feat: Created Course updates page (#581) 2023-08-31 10:56:45 -04:00
Jesper Hodge
8fe8bc1587 docs: document jest troubleshooting (#382) 2023-08-28 12:05:47 -04:00
mashal-m
e23a0887ce refactor: update lock file version 2023-08-28 13:54:54 +05:00
kenclary
8e659527f0 Merge pull request #366 from open-craft/farhaan/fix-drag-drop-component
Re-write the dropzone component and fix styling issues
2023-08-25 12:50:24 -04:00
Kristin Aoki
181f9c7a5f feat: add sort function and modal (#577)
* feat: add sort modal and function

* fix: dateAdded typo

* chore: update mock api data
2023-08-25 10:08:15 -04:00
Jhon Vente
1d95af5a31 [DOCS] Readme updated according OEP-55 (#526) 2023-08-24 09:16:27 -04:00
Kristin Aoki
d7a4b5b45b fix: add word break style for long words (#574) 2023-08-23 15:17:26 -04:00
kenclary
45e4bc5376 Merge pull request #368 from open-craft/kshitij/fix-video-sort-filter
fix: Video Gallery filters and sorting
2023-08-23 06:43:56 -07:00
vladislavkeblysh
2e8eed7504 feat: Created Course Team (#564) 2023-08-23 09:21:43 -04:00
German
d768bfc97a fix: xpert unit sumamries settings ui fixes (#576)
1. https://jira.2u.com/browse/ACADEMIC-16289
2. https://jira.2u.com/browse/ACADEMIC-16422
2023-08-22 15:43:17 -03:00
Jesper Hodge
9c997ab845 fix: Pass correct prop to TinyMceWidget and update FLCC (#575)
* fix: Pass correct prop to TinyMceWidget

* chore: update flcc

* fix: lockfile
2023-08-22 13:28:30 -04:00
kenclary
259b9f3d1f fix: don't get returnUrl for v2 blocks. (#380) 2023-08-21 19:57:08 -04:00
Kristin Aoki
c1976ce4d3 feat: add delete confirmation modal (#570) 2023-08-21 17:28:49 -04:00
Kristin Aoki
be74de2b22 fix: file info bugs (#571) 2023-08-21 16:47:52 -04:00
Jesper Hodge
e691df9cb5 fix: answer text flipped (#379)
This fixes a bug where an answer text was flipped in terms of the character order when typing (TNL-10980). One of the prop names of the TinyMceWidget that is imported in course-authoring had to be changed, so this goes together with https://github.com/openedx/frontend-app-course-authoring/pull/575.
2023-08-21 16:43:46 -04:00
German
fda1208660 feat: add xpert summaries configuration by default for units (#567)
* feat: add xpert summaries configuration by default for units
2023-08-21 16:14:39 -03:00
Farhaan Bukhsh
b7a04e17da fix: Fixing the accessing of undefined variables in video
Signed-off-by: Farhaan Bukhsh <farhaan@opencraft.com>
2023-08-21 10:11:56 +05:30
Farhaan Bukhsh
f822d95d6a fix: Used Dropzone instead of having custom component
This PR fixes style component and remove any new component introduced.
We introduce a new thumbnail for setting page as well.

Signed-off-by: Farhaan Bukhsh <farhaan@opencraft.com>
2023-08-21 10:11:56 +05:30
kenclary
12266836eb Merge pull request #378 from openedx/kenclary/supplemental
fix: revert to blank-url version of error handling, for now
2023-08-18 14:09:29 -07:00
Ken Clary
3c1f870aac fix: revert to blank-url version of error handling, for now 2023-08-18 13:46:57 -07:00
kenclary
6de926ce7e Merge pull request #377 from openedx/kenclary/supplimental
fix: don't even bother fetching block ancestor in v2.
2023-08-17 17:37:31 -04:00
Ken Clary
9079196309 fix: don't even bother fetching block ancestor in v2. 2023-08-17 14:23:13 -07:00
Kristin Aoki
b65f4f2b74 feat: bump frontend-lib-content-components (#569) 2023-08-17 11:26:39 -04:00
Kshitij Sobti
fb7caffdd5 feat: Allow selecting my multiple filters in video gallery
The sort and filter UI of the video gallery was not working, this fixes that
issue, and also adds a new UI for filering videos that allows filtering videos
to include more than one status.

It also fixes the hooks related to VideoGallery to avoid potential bugs in the
future and updates tests to use react testing library instead of enzyme.

It also reduces the padding in gallery page.
2023-08-17 13:21:47 +05:30
Kristin Aoki
9438a5b89a feat: add typeahead component (#375) 2023-08-16 18:18:06 -04:00
David Nuon
530c355787 fix: Add enabled badge to xpert settings tile (#566)
* feat: Add "Enabled" badge to xpert settings tile

* fix: Update model with state instead of non-existent prop from response
2023-08-15 09:17:58 -07:00
sundasnoreen12
fc21e22afb test: added test cases of discussion restriction (#556)
* test: added test cases of discussion restriction

* refactor: added null default value for dataTestId

---------

Co-authored-by: SundasNoreen <sundas.noreen@arbisoft.com>
2023-08-15 14:38:45 +05:00
Peter Kulko
f9bc5c4927 feat: created Grading page (#557) 2023-08-14 14:44:01 -04:00
Kristin Aoki
484b141328 fix: overflow-y scroll behavior (#565) 2023-08-14 12:10:53 -04:00
Kristin Aoki
dc0762312e feat: bump frontend-lib-content-components (#562) 2023-08-11 14:29:57 -04:00
Kristin Aoki
e9c0f6cc82 fix: selectedVideo undefined error (#374) 2023-08-11 14:05:07 -04:00
Raymond Zhou
33f46be993 feat: flcc to 1.168.0 (#561) 2023-08-11 13:05:02 -04:00
Kristin Aoki
d1c176cfc8 fix: width and height of asset preview (#558) 2023-08-10 16:54:51 -04:00
Raymond Zhou
a18c45f0db feat: call failRequest on fetch failure (#373) 2023-08-10 12:58:14 -04:00
David Nuon
17d14968fa fix: Change wording to not crowd xpert tile in preferences page (#560) 2023-08-09 12:40:14 -07:00
Kristin Aoki
df51130fce feat: bump frontend-lib-content-components (#559) 2023-08-09 15:22:41 -04:00
Kristin Aoki
669fbfb3d2 fix: blockId checks for v1 or v2 libraries (#372) 2023-08-09 14:55:46 -04:00
Kristin Aoki
bc05d2c01e feat: upgrade frontend-lib-content-components (#554) 2023-08-08 13:03:08 -04:00
Kristin Aoki
918370f743 fix: error return while editor loading (#369) 2023-08-08 12:41:15 -04:00
ruzniaievdm
a0e37c0357 feat: Added Schedule and Details MFE page (#547) 2023-08-08 09:49:53 -04:00
sundasnoreen12
a218e7e5f8 test: added test cases for hide discussion tab (#552)
Co-authored-by: SundasNoreen <sundas.noreen@arbisoft.com>
2023-08-08 14:11:41 +05:00
David Nuon
f2a4386892 Update verbiage for Xpert Settings (#550)
* chore: Update verbiage for Xpert configuration screen

* fix: Change "generate" to "display" in xpert modal text

* fix: Updated learn more link

* fix: Change link and add targets
2023-08-07 07:17:40 -07:00
Kristin Aoki
c9b111a022 fix: remove env variable for files and uploads (#549) 2023-08-04 14:25:05 -04:00
Kristin Aoki
b9feb50a2c feat: add files and uploads page (#541) 2023-08-04 11:57:44 -04:00
ruzniaievdm
d25ae09273 feat: Add TinyMceWidget on export (#365) 2023-08-03 12:44:07 -04:00
Zachary Hancock
7fdf8da8ed fix: load up-to-date config on studio fetch (#548) 2023-08-01 15:37:13 -04:00
David Nuon
1dba6208a5 feat: configuration for xpert unit summaries (#540)
Adds setting modal for Xpert unit summaries

Includes hiding the config section for xpert summary - 
this is done based on a flag from 3d113d267c
2023-08-01 09:07:08 -04:00
Kristin Aoki
9f4422d1b9 fix: ui bugs (#542) 2023-07-31 17:23:07 -04:00
kenclary
38b85f70ac Merge pull request #343 from Mashal-m/mashal-m/react-upgrade-to-v17
feat: update react & react-dom to v17
2023-07-31 14:54:39 -04:00
mashal-m
cc4a7cc83d build: update lock file 2023-07-31 16:52:05 +05:00
mashal-m
3f98349f94 build: update lock file 2023-07-31 16:47:50 +05:00
mashal-m
ed7e98b6ea Merge branch 'main' of https://github.com/openedx/frontend-lib-content-components into mashal-m/react-upgrade-to-v17 2023-07-31 16:23:46 +05:00
Omar Al-Ithawi
8bfc3f2945 feat: include paragon in atlas pull (#538)
This pull request is part of the [FC-0012 project](https://openedx.atlassian.net/l/cp/XGS0iCcQ) which is sparked by the [Translation Infrastructure update OEP-58](https://open-edx-proposals.readthedocs.io/en/latest/architectural-decisions/oep-0058-arch-translations-management.html#specification).
2023-07-25 11:16:29 -04:00
Kristin Aoki
0e1a7e2603 feat: make placeholder depend on api response (#537) 2023-07-25 10:32:31 -04:00
sundasnoreen12
cc7fc6a9e1 chore: add paragon messages (#530) (#534)
Co-authored-by: Mashal Malik <107556986+Mashal-m@users.noreply.github.com>
2023-07-24 19:13:20 +05:00
Mashal Malik
da1e7a0277 chore: add paragon messages (#530) 2023-07-21 11:08:39 +05:00
kenclary
a935d296c9 Merge pull request #355 from openedx/kenclary/TNL-10743
feat: more/correct v2 url handling. TNL-10742
2023-07-20 15:31:33 -04:00
Jesper Hodge
3565741839 fix image resize (#299)
Description:
This is a bug where the image resizing in text editor and problem editor was completely broken. Putting in a text value when the aspect ratio lock was enabled would change both values but not to the size you wanted. If you disabled the lock, not just one but both values would change.

This is a problem that mostly affects images that are rectangular, not square. There's an example image below which is one that caused problems on prod.

Main fixes:
when I keep the image ratio locked, I can change one value (like width) and the other will jump to the proportionate value, but rounded to full pixels.
when I unlock the aspect ratio and change a value, then click save on the image dimension modal, only the one value will change, which will stretch the image in whatever direction. This is reflected in the tinymce image and then the updated value will appear when I reopen the image dimension modal. It is not possible to reset the image to the original dimensions any longer. The new values are saved.
The image dimensions in the edit image settings modal should always reflect the actual dimensions of the image when I look at it e.g. in the course outline. (Otherwise I may click save and the image is squished.)
There was a problem with deselecting an image: when you edit image dimensions and then save or press cancel, the "edit image" button will not disappear, but the image is not selected anymore. When you do not click anything else but immediately click on this button, sometimes (at least the second or third time you do this) this will throw an error. I fixed it so it will just open the default "select image" modal.
Other requirements:
Resizing the image means that when I open the dimensions update, I see the new dimensions.
Images in the editor are now displayed with the correct dimensions, proportional or stretched, if those dimensions don't exceed the size of the editor.
A known smaller bug emerging from this is that when you have more than one instance of the same image in the same editor, you cannot get or set its dimensions correctly. I believe I have gotten it into the following state: When you click one of the copies, you will either get the correct dimensions of the selected copy, or if not, it will display the original image dimensions. When you edit the dimensions, the correct copy of the image will be updated.
Out of Scope:
This cannot handle more than one instance of the same image properly. There will be a separate bug issue for this.
Sometimes, when you edit image dimensions and then reopen the image dimension modal, the dimensions will be null and thus just not appear in the modal - randomly. This is a bug as well.
2023-07-20 14:52:21 -04:00
Ken Clary
7178e5e4c9 feat: more/correct v2 url handling. TNL-10742 2023-07-20 14:37:22 -04:00
Raymond Zhou
4a5eaaf15e feat: setup game editor work (#363) 2023-07-20 04:59:54 -04:00
Peter Kulko
87ead24e20 feat: added Advanced settings page (#521)
Co-authored-by: sendr <sendr84@gmail.com>
Co-authored-by: ruzniaievdm <ruzniaievdm@gmail.com>
2023-07-19 10:45:50 -04:00
Kristin Aoki
e05e6325c9 fix: marketing base url typo (#533) 2023-07-17 11:35:39 -04:00
Leangseu Kim
b090c8c153 feat: add open responses card to page and resources 2023-07-13 11:07:58 -04:00
Kristin Aoki
7939af4737 fix: partner portal typo (#362) 2023-07-11 14:10:04 -04:00
Kristin Aoki
3c3dfeb325 feat: use new studio footer (#532) 2023-07-11 13:05:10 -04:00
Kristin Aoki
3586307ee7 feat: react based studio footer (#359) 2023-07-11 10:30:52 -04:00
Ghassan Maslamani
2bc447fab0 fix: resolve #360 make style consistent across outlines
This changes make the style consistent across the first three
 headline line levels

 1. The first level add CSS prop initial
 2. The second level change prop from capital to inital
 3. No change
2023-07-11 14:50:29 +03:00
Jesper Hodge
f942ef9594 fix enable rules of hooks (#329)
This is a PR enabling eslint "rules-of-hooks".

This lint rule catches some very annoying bugs and enforces you to use correct naming for custom hooks (prepend with "use"), which is a mandatory react rule and important for a number of reasons.

I added eslint-disable statements wherever the rules are broken, and if this is merged, I would expect new code not to break the rules any longer.

I strongly suggest that the much better way to extract and reuse hooks and logic from components is the way the community does it and the React docs suggest. The new React docs are really fantastic in this regard and you can use the patterns found there very well to have an excellent application. https://react.dev/learn/reusing-logic-with-custom-hooks
2023-07-05 15:11:07 -04:00
mashal-m
505704e8f3 build: update edx pkgs and peer Dep 2023-07-05 16:44:24 +05:00
kenclary
7ee8cc7fb1 feat: update flcc to 1.62.0 (#528) 2023-06-30 15:41:54 -04:00
Raymond Zhou
912fff9b0f feat: update flcc to 1.61.0 (#527) 2023-06-30 11:59:46 -04:00
kenclary
c09faa3b09 Merge pull request #354 from open-craft/farhaan/bb-7522-fix-spinner-for-video
feat: Add loading spinner to the video upload page
2023-06-30 11:10:50 -04:00
kenclary
2ab7aa5cea Merge pull request #350 from open-craft/navin/hide-hide-option
refactor: hide switch to hide selected videos
2023-06-30 11:10:42 -04:00
Kristin Aoki
2c71385ce7 fix: env custom pages conditional render (#525) 2023-06-29 10:45:56 -04:00
Raymond Zhou
436fdfc470 feat: parse out explanation text (#358) 2023-06-28 14:05:31 -04:00
Kristin Aoki
139457087b feat: add custom pages (#510) 2023-06-27 16:26:35 -04:00
Raymond Zhou
3a26285bd1 feat: update flcc to 1.60.0 (#523) 2023-06-27 13:19:26 -04:00
Raymond Zhou
86b67022ba feat: parser changes (#356) 2023-06-27 12:50:07 -04:00
Navin Karkera
7a53de4f2d refactor: hide switch to hide selected videos
The backend for hiding selected videos is not implemented and it is currently not required, so this commit hides the option.
2023-06-24 19:39:38 +05:30
Farhaan Bukhsh
ab640fb561 refactor: Moved the function to hooks in order to keep the components
dumb

It is done to make sure the business logic is not in a component and can
be individually tested.

Signed-off-by: Farhaan Bukhsh <farhaan@opencraft.com>
2023-06-23 20:01:33 +05:30
Farhaan Bukhsh
4d684d620e fix: Added tests for video upload
Signed-off-by: Farhaan Bukhsh <farhaan@opencraft.com>
2023-06-23 20:01:33 +05:30
Kristin Aoki
714c946f0f fix: persisting title from previous editor load (#353) 2023-06-22 19:22:40 -04:00
kenclary
769cdb08fb Merge pull request #344 from jansenk/events
feat: send event on checkbox change
2023-06-22 10:37:20 -04:00
jansenk
1a0cc2db2a style: rename function 2023-06-22 09:26:11 -04:00
Farhaan Bukhsh
a86b844208 feat: Add spinner to video element to load
Signed-off-by: Farhaan Bukhsh <farhaan@opencraft.com>
2023-06-22 13:46:08 +05:30
Kristin Aoki
c8e85fae0b fix: failure toast and close modal bugs (#352) 2023-06-21 13:48:54 -04:00
mashal-m
42210e7c89 build: update lock file 2023-06-21 14:16:10 +05:00
mashal-m
ef662f9ceb Merge branch 'main' of https://github.com/openedx/frontend-lib-content-components into mashal-m/react-upgrade-to-v17 2023-06-21 14:10:01 +05:00
Mashal Malik
8a2c725eda chore: update lock version file (#351) 2023-06-21 05:03:50 -04:00
mashal-m
530183a297 build: update paragon version 2023-06-19 15:55:53 +05:00
Kristin Aoki
b0fef766eb feat: add ErrorAlert to exports (#349) 2023-06-15 15:28:12 -04:00
Raymond Zhou
e2c1deaeb3 feat: flcc to 1.157.0 (#520) 2023-06-14 14:07:42 -04:00
Raymond Zhou
83f034e500 feat: save spacing for richText parser (#348) 2023-06-14 12:04:44 -04:00
Kristin Aoki
61baf1a886 chore: bump frontend-lib-content-components (#518) 2023-06-13 16:51:29 -04:00
kenclary
ac2444c258 Merge pull request #347 from openedx/kenclary/TNL-10742
feat: v2 xblocks should use v2 url. TNL-10742
2023-06-13 16:32:44 -04:00
Kristin Aoki
665a53a713 feat: add draggable list (#342) 2023-06-13 16:31:17 -04:00
Kristin Aoki
8eb10b7b12 feat: update returnToUnit to include api response (#346) 2023-06-13 15:29:04 -04:00
Ken Clary
ffd311881a feat: v2 xblocks should use v2 url. TNL-10742 2023-06-13 15:09:04 -04:00
Maria Grimaldi
51e5e7126c fix: cast progress graph configuration to string (#495) 2023-06-12 11:10:59 -04:00
jansenk
491d870cd2 style: quality 2023-06-12 10:25:04 -04:00
jansenk
e2535b2467 feat: send event on checkbox change 2023-06-12 09:56:32 -04:00
jansenk
0111d1c2f5 fix: remove param from end of video features url 2023-06-12 09:56:07 -04:00
mashal-m
86b0c4da82 feat: update react & react-dom to v17 2023-06-12 18:13:45 +05:00
Jenkins
a53a93ccee chore(i18n): update translations 2023-06-11 17:32:51 -04:00
Kristin Aoki
82b0f67f11 feat: add returnUrl prop to editors (#341) 2023-06-08 13:32:53 -04:00
Dmytro
e980f1f20e fix: disable invalid link Video Uploads (#511) 2023-06-08 11:06:11 -04:00
Kristin Aoki
fac9eab496 feat: bump frontend-lib-content-components (#509) 2023-06-06 11:38:57 -04:00
Kristin Aoki
f3c4669604 fix: doc typos (#340) 2023-06-06 11:00:37 -04:00
ayesha waris
1b1afcf195 feat: integrated backend discussions restriction with UI (#507)
* feat: integrated backend discussions restriction with UI

* refactor: code refactoring

* test: fixes test cases

* refactor: discussion restriction component

---------

Co-authored-by: ayesha waris <73840786+ayeshoali@users.noreply.github.com>
Co-authored-by: Awais Ansari <awais.ansari63@gmail.com>
2023-06-06 14:55:19 +05:00
kenclary
43b6ec7708 Merge pull request #339 from openedx/revert-338-kenclary/update-react
Revert "chore: update react to 17, etc. TNL-10715"
2023-06-05 16:43:00 -04:00
kenclary
6317c46120 Revert "chore: update react to 17, etc. TNL-10715" 2023-06-05 16:38:58 -04:00
Kristin Aoki
831c6096cb fix: choice parsing for answers with multi lines (#337) 2023-06-02 11:13:33 -04:00
kenclary
dd79d49533 Merge pull request #338 from openedx/kenclary/update-react
chore: update react to 17, etc. TNL-10715
2023-06-02 09:17:51 -04:00
Ken Clary
648e700818 chore: update react to 17, etc. TNL-10715 2023-06-01 16:11:58 -04:00
Kristin Aoki
788f671626 feat: bump frontend-lib-content-components (#506) 2023-05-31 14:27:04 -04:00
Kristin Aoki
88629d6df1 fix: olx parsers with formatted text (#336) 2023-05-30 11:42:59 -04:00
Jenkins
ac7b4c9fcf chore(i18n): update translations 2023-05-28 17:32:49 -04:00
Bilal Qamar
2199a24dd7 feat: upgraded to node v18, added .nvmrc and updated workflows (#281)
Co-authored-by: Abdullah Waheed <abdullah.waheed@arbisoft.com>
2023-05-26 09:52:56 -04:00
Mashal Malik
9a4af8ff2e feat: upgraded to node v18, added .nvmrc and updated workflows (#464)
* feat: upgraded to node v18, added .nvmrc and updated workflows

* feat: upfate validate workflow

* feat: update validate workflow

* fix: update lock file

* refactor: update validate file

* build: update pkg

* refactor: updated packages

* build: updated frontend-build, frontend-platform, component-footer & component-header packages

* refactor: updated workflow

* refactor: updated workflow

* refactor: updated workflow

* build: update commit file

* build: update lock file

* refactor: update workflow

* refactor: update workflow

* refactor: update workflow

* refactor: update workflow

* build: update pkg

* build: update pkgs

* build: update lock file

---------

Co-authored-by: Bilal Qamar <59555732+BilalQamar95@users.noreply.github.com>
2023-05-25 13:49:24 +05:00
Kristin Aoki
d80b6faaad feat: replace canvas with jest-canvas-mock (#335) 2023-05-24 09:56:39 -04:00
kenclary
9cfd8013d2 feat: update frontend-lib-content-components to v1.151.2 (#503) 2023-05-22 11:06:42 -04:00
Kristin Aoki
e0c0c918d0 fix: feedback clearing on type change (#334) 2023-05-22 09:57:22 -04:00
Jenkins
74f5a0e8ee chore(i18n): update translations 2023-05-21 17:32:46 -04:00
sundasnoreen12
0d67c2588d feat: implemented discussion restriction UI (#494)
* feat: implemented discussion restriction UI

* refactor: fixed UI figma design issues

* refactor: fixed 2nd review points

* refactor: fixed review issues regarding confirmation popup

* refactor: changed tab component to button group

* perf: performance improvement changes

* refactor: fixed memorization issues

* refactor: fixed memo issues

---------

Co-authored-by: sundasnoreen12 <sundasnoreen12@ggmail.com>
Co-authored-by: SundasNoreen <sundas.noreen@arbisoft.com>
2023-05-19 17:16:48 +05:00
Kristin Aoki
738f501cf9 feat: add new header and page routes (#501) 2023-05-18 17:08:38 -04:00
kenclary
9239d2b8b1 Merge pull request #333 from open-craft/chris/video-editor-flow-fix
fix: Temporal testing line deleted from VideoUploadEditor::hooks.js
2023-05-18 12:42:39 -04:00
XnpioChV
3bdafd6e36 fix: Temporal testing line deleted from VideoUploadEditor::hooks.js 2023-05-18 11:31:35 -05:00
kenclary
aee971924f Merge pull request #326 from open-craft/chris/FAL-3383-new-video-editor-flow
[FAL-3383] Implement new video UX flow on new video editor
2023-05-18 11:49:10 -04:00
Chris Chávez
ff6a5d99d6 [FAL-3383] Implement new video UX flow on new video editor (#498)
* feat: Video Gallery URL updated to match to the new flow needs

* chore: Video Gallery Url updated and blockId added
2023-05-18 09:55:33 -04:00
Raymond Zhou
a46a34412c feat: update flcc to 1.150.1 (#500) 2023-05-17 15:43:48 -04:00
Raymond Zhou
741b83bdf2 fix: delete answers without changing expandable (#328) 2023-05-17 14:22:51 -04:00
Kristin Aoki
be8f9ecc86 feat: add raw olx settings parser (#332) 2023-05-15 15:12:32 -04:00
Mashal Malik
084d61ffa1 Update codecov and add browserslist config (#209)
* refactor: update code cov and add browserlist config
2023-05-11 14:44:48 -04:00
Kristin Aoki
99cd3bf1d9 chore: refactor OLXParser and related doc strings (#330) 2023-05-11 13:30:47 -04:00
Jesper Hodge
8cd222b9fa Add ADR for organizing our folder structure in a feature-based manner (#296)
* docs: add feature based application organization adr

* Update 0006-feature-based-application-organization.rst

* docs: update adr
2023-05-11 12:06:11 -04:00
Kristin Aoki
db6c3172de feat: bump frontend-lib-content-components (#499) 2023-05-11 10:31:23 -04:00
Kristin Aoki
1d66a9d14d feat: remove matlab api widget and refs (#331) 2023-05-10 15:17:16 -04:00
Omar Al-Ithawi
0d38279950 feat: use atlas in make pull_translations (#490)
Changes
-------
 - Bump frontend-platform to bring `intl-imports.js` script
 - Move all i18n imports into `src/i18n/index.js` so `intl-imports.js` can
   override it with latest translations
 - Add `atlas` into `make pull_translations` when `OPENEDX_ATLAS_PULL`
   environment variable is set.

Refs: [FC-0012 project](https://openedx.atlassian.net/l/cp/XGS0iCcQ) implementing Translation Infrastructure OEP-58.
2023-05-09 10:13:50 -04:00
Kristin Aoki
109334a9bf fix: show setting note for course set social share (#327) 2023-05-09 09:27:32 -04:00
Jesper Hodge
003f33152d docs: add adr with test naming conventions (#320)
* docs: add adr with test naming conventions

* docs: fix rst

* docs: add further reading section

* Update docs/decisions/0006-test-names.rst
2023-05-05 16:20:19 -04:00
XnpioChV
5c432a03db test: Adding missing test to reach coverage/patch 2023-05-05 14:10:18 -05:00
Kristin Aoki
3dd28082ea chore: bump frontend-lib-content-components (#497) 2023-05-05 11:01:36 -04:00
XnpioChV
15393f3da1 style: Fixing styles on gallery, editor and uploader video page 2023-05-04 18:00:06 -05:00
XnpioChV
135e0d7859 feat: Adding navigation on the url input of the video uploader page 2023-05-04 17:31:56 -05:00
XnpioChV
e20dedd0a5 feat: Allow to import transcripts from selected video 2023-05-04 17:31:55 -05:00
Pooja Kulkarni
359a5fd505 feat: Create new editor page for video upload 2023-05-04 17:31:54 -05:00
XnpioChV
da00ad7539 chore: All selection and save flow added 2023-05-04 17:01:42 -05:00
XnpioChV
23593b44fe chore: Error message on unselected video added & replace video button navigation added 2023-05-04 16:59:31 -05:00
XnpioChV
d2b3edad57 feat: Adding blockId to the Gallery. Adding cancel and next navigation 2023-05-04 16:58:36 -05:00
Raymond Zhou
adc21735fc fix: expandable textarea should save on blur (#325) 2023-05-04 17:17:14 -04:00
Kristin Aoki
34d6fcc552 feat: allow social share widget in libraries (#324) 2023-05-04 13:25:28 -04:00
Kristin Aoki
767283cbc6 chore: bump frontend-lib-content-components (#496) 2023-05-03 10:56:28 -04:00
Kristin Aoki
c49779a293 feat: add a button to return to studio (#322) 2023-05-03 10:35:02 -04:00
Kristin Aoki
6aaedfc500 feat: add social share widget (#323) 2023-05-03 09:55:31 -04:00
Jenkins
0066902127 chore(i18n): update translations 2023-04-30 17:32:45 -04:00
Raymond Zhou
9a567b875e feat: update flcc to 1.45.0 (#492) 2023-04-27 15:13:29 -04:00
Raymond Zhou
d68bdf9dc6 feat: page errors indefinitely with no ancestor (#321) 2023-04-27 14:38:59 -04:00
kenclary
76ad7d8bda Merge pull request #262 from open-craft/pooja/bb7157-add-video-upload-feature
[BB-7157] Create new editor page for video upload
2023-04-26 13:41:37 -04:00
Pooja Kulkarni
bef6813d2c feat: Create new editor page for video upload 2023-04-26 11:36:26 -04:00
Kristin Aoki
a7f877caf5 feat: bump flcc and paragon (#491) 2023-04-26 10:23:03 -04:00
Kristin Aoki
bade92f613 feat: remove custom css with paragon upgrade (#319) 2023-04-26 09:55:40 -04:00
Kristin Aoki
21841fe09f fix: editable header width (#318) 2023-04-26 09:13:04 -04:00
Raymond Zhou
e75928a774 feat: update flcc to 1.142.0 (#489) 2023-04-25 16:31:58 -04:00
Raymond Zhou
8676ba257c feat: default randomization to never (#317) 2023-04-25 16:14:40 -04:00
kenclary
eaab798da2 Merge pull request #278 from open-craft/chris/FAL-3375-video-selection-gallery
[FAL-3375] Feat: Video selection gallery page
2023-04-25 15:54:05 -04:00
Chris Chávez
4b7f46852b [FAL-3375] Feat: Adding video selection gallery page to the routes (#461)
* feat: Adding video selection gallery page to the routes

* test: CourseAuthoringRoutes.test.jsx added
2023-04-25 12:45:00 -04:00
Pooja Kulkarni
1e0c128ad6 fix: make blockid parameter optional (#455) 2023-04-25 11:36:58 -04:00
Yoiber
e3887129fc chore(i18n): add more languages (#450)
* chore(i18n): add more languages

* chore(i18n): Pylint fixes

* chore(i18n): Typo to named the imports
2023-04-25 08:58:37 -04:00
ayesha waris
2eaf882734 fix: only global staff can see 2 edx discussion providers in settings (#477)
* fix: only global staff can see 2 edx discussion providers in settings

* test: adds and updated test cases for app list

* refactor: memoized showoneedxprovider constant

---------

Co-authored-by: ayesha waris <73840786+ayeshoali@users.noreply.github.com>
2023-04-25 15:00:35 +05:00
Jenkins
284c402a49 chore(i18n): update translations 2023-04-23 17:32:44 -04:00
XnpioChV
5695f92127 chore: Padding on gallery fixed 2023-04-21 18:06:10 -05:00
XnpioChV
36e56588cb test: Adding test for VideoGallery and SelectionModal 2023-04-21 18:06:09 -05:00
XnpioChV
b3bced9875 feat: New screens for loading, no videos and error states. Also tests added 2023-04-21 18:06:08 -05:00
XnpioChV
71efe876d3 style: adding more styles on the selection modal 2023-04-21 18:04:06 -05:00
XnpioChV
3b69958427 feat: Search and filters added 2023-04-21 18:04:05 -05:00
XnpioChV
b78e58cd2a feat: New request hook to fetch videos 2023-04-21 18:04:05 -05:00
XnpioChV
14504073e0 feat: Video selection page created
The SelectImageModal component has been refactored so that it can also be used on the video selection page; and all its child components.
Now this component is called SelectionModal and is used both for the image selector and in this new video selection screen.
The assets api has been used to get the videos.
2023-04-21 18:04:04 -05:00
Raymond Zhou
2a5f6795d3 feat: tinyMCE formatting and parsing (#311) 2023-04-21 11:42:10 -04:00
connorhaugh
802d328f4a feat: remove layered button (#314) 2023-04-21 11:04:23 -04:00
connorhaugh
d08eb0e3a9 feat: upgrade flcc (#487) 2023-04-21 10:41:37 -04:00
Kristin Aoki
c37e6957f6 fix: advanced editor not saving (#315) 2023-04-21 10:25:01 -04:00
Kristin Aoki
492ee27d8e fix: settings helper text font size (#313) 2023-04-21 09:19:39 -04:00
Raymond Zhou
80461755d1 feat: hint trash button should not be squished (#312) 2023-04-20 16:49:43 -04:00
Kristin Aoki
76b7623cb0 feat: bump frontend-lib-content-components 1.137.0 (#486) 2023-04-20 13:41:47 -04:00
Kristin Aoki
b674cd0cb0 feat: add no answer confirmation alert (#310) 2023-04-20 12:49:07 -04:00
connorhaugh
1e25091698 feat: add hotjar tracking (#485) 2023-04-19 16:56:18 -04:00
Kristin Aoki
8f15480c28 feat: update problem descriptions (#309) 2023-04-18 13:23:18 -04:00
Kristin Aoki
4f1dc98ecc fix: settings font size and spacing (#308) 2023-04-18 11:56:20 -04:00
Jenkins
1289f7d4e2 chore(i18n): update translations 2023-04-16 17:27:42 -04:00
Kristin Aoki
eb1b2eb883 feat: bump frontend-lib-content-components 1.135.1 (#483) 2023-04-14 16:44:30 -04:00
Kristin Aoki
405003045c fix: textArr join error in syntaxChecker (#307) 2023-04-14 16:28:16 -04:00
Kristin Aoki
74e45139bf feat: bump frontend-lib-content-components 1.135.0 (#482) 2023-04-14 12:20:52 -04:00
Kristin Aoki
1d2a4c212d feat: add xml linter to code mirror (#306) 2023-04-14 11:58:49 -04:00
Raymond Zhou
f9a240ade4 feat: update FLCC to 1.134.0 (#481) 2023-04-13 17:59:54 -04:00
Raymond Zhou
4b7b1c91ec feat: further number parse changes (#305) 2023-04-13 17:31:03 -04:00
Raymond Zhou
b09e7f3683 feat: update FLCC to ver1.133.0 (#480) 2023-04-13 13:12:20 -04:00
Raymond Zhou
286d2209cb feat: XMLBuilder and XMLParser performing unwanted processing in encoding / parsing (#304) 2023-04-13 12:25:43 -04:00
sundasnoreen12
b19d52555f refactor: removed all extra messages files (#475)
Co-authored-by: sundasnoreen12 <sundasnoreen12@ggmail.com>
2023-04-13 17:13:49 +05:00
Raymond Zhou
ab4dd9a4a8 feat: update FLCC to 1.132.0 (#476) 2023-04-11 14:17:58 -04:00
Raymond Zhou
1e6d8b51e4 feat: show reset for advanced problem editor (#302) 2023-04-11 12:53:53 -04:00
connorhaugh
73a4b893f7 Feat parse solution as sibling (#303)
* fear: parse solution as siblings

* feat: add error resliancy to solution check.
2023-04-11 09:23:02 -04:00
connorhaugh
a94942a36e Feat update flcc for cat 2 part deux (#473)
* feat: update flcc for cat-2

* feat: updte flcc for cat-2 part deux
2023-04-10 15:55:59 -04:00
connorhaugh
d58f349e1f feat: parse solution as siblings (#301)
this creates the ability for explanations to work if they are:

Not a child of a response type
Use an h2 tag for the explanation title
do not use the "Explanation" title.
2023-04-10 15:37:02 -04:00
connorhaugh
ab7c51994c feat: update flcc for cat-2 (#472) 2023-04-10 10:58:59 -04:00
connorhaugh
8a7dbdf4be fix: parse description/label as children (#300)
* fix: parse description/label as children

* fix: bounce problem tag attributes to advanced
2023-04-10 10:38:30 -04:00
Kristin Aoki
284139e247 feat: add check to sanitize answer ranges (#298) 2023-04-07 09:04:15 -04:00
Raymond Zhou
67967a92cf feat: update FLCC to 1.129.0 (#471) 2023-04-06 14:12:09 -04:00
Raymond Zhou
9a19711755 feat: revert group feedback expanded text field (#297) 2023-04-06 13:40:13 -04:00
Kristin Aoki
4cfc5a6ea6 feat: add alert to notify video id changes (#295) 2023-04-06 12:34:07 -04:00
connorhaugh
6efa8c5356 feat: upgrade flcc to 125 (#470) 2023-04-05 10:24:15 -04:00
connorhaugh
82cfa9897c feat: default scoring to 1, not zero. (#294)
Since every course has graded problems, every course author will be editing or creating problems, and every learner will need to receive points for any problem in a graded assignment in order to earn a passing grade. So if what I encountered and am reporting here is reproducible, this should probably be addressed before the problem editor feature is released.
2023-04-05 09:36:20 -04:00
Kristin Aoki
c28669f5b2 feat: upgrade flcc package to 1.126.1 (#469) 2023-04-04 09:54:05 -04:00
Kristin Aoki
bd964854de fix: misspelling of explanation in description (#293) 2023-04-03 13:56:50 -04:00
Kristin Aoki
f99421f493 feat: add catch for script tags in question (#292) 2023-04-03 11:50:35 -04:00
connorhaugh
c2b67429d3 feat: add answer range (#291)
* feat: add answer range

* feat: add margin for doropdown

* fix: improve test converage
2023-03-30 10:34:45 -04:00
Omar Al-Ithawi
98ec415e2b fix: let make extract_translations find messages (#290)
Otherwise it'll complain for not finding any message.

`defineMessage` ensures that React i18n static code collector is able to
find the messages.

References
----------

This pull request is part of the [FC-0012 project](https://openedx.atlassian.net/l/cp/XGS0iCcQ) which is sparked by the [Translation Infrastructure update OEP-58](https://open-edx-proposals.readthedocs.io/en/latest/architectural-decisions/oep-0058-arch-translations-management.html#specification).

Check the links above for full information about the overall project.
2023-03-29 10:17:25 -04:00
kenclary
270f4a8a12 chore: upgrade frontend-lib-content-components to 1.124.0. (#468) 2023-03-27 13:57:44 -04:00
kenclary
e7d69f4e5d Merge pull request #289 from openedx/kenclary/TNL-10535
fix: ErrorPage rewritten as functional component with injected i18n. TNL-10535
2023-03-24 16:40:10 -04:00
Ken Clary
f2ad93789f fix: ErrorPage rewritten as functional component with injected i18n. TNL-10535 2023-03-24 16:22:32 -04:00
connorhaugh
3bfa83220f feat: error on funky multiple choice tags. (#288)
This change increases the frequency at which odd tags (like shuffle) on multiple choice problems don't go to the visual editor.
Instead, they will now divert to the advanced editor. There might be other places where we need to follow a similar pattern, but we don't know those yet.
2023-03-24 10:05:21 -04:00
Kristin Aoki
7ef1963327 feat: add default advanced setting ui callouts (#285) 2023-03-23 17:37:13 -04:00
Ken Clary
4410f0a544 Merge branch 'keith/video-preview-widget' 2023-03-23 14:59:56 -04:00
Ken Clary
ed0aa88841 chore: fixup from rebase 2023-03-23 14:59:38 -04:00
Ken Clary
7080189a65 chore: fixup from rebase 2023-03-23 14:56:49 -04:00
Ken Clary
7a27b65a8c Merge branch 'keith/video-preview-widget' 2023-03-23 14:19:24 -04:00
Keith Grootboom
57a558f258 chore: use Hyperlink instead 2023-03-23 14:18:16 -04:00
Keith Grootboom
475c32463a refactor: review changes to use existing youtube function 2023-03-23 14:18:16 -04:00
Keith Grootboom
b4fb88c73c feat: add video preview widget to settings modal 2023-03-23 14:18:10 -04:00
kenclary
c7c0d5e100 Merge pull request #258 from open-craft/0x29a/video-duration-widget-improvements
feat: video duration section improvements [BD-12]
2023-03-23 11:47:31 -04:00
kenclary
21e01d1b77 Merge pull request #284 from open-craft/maxim/transcripts-section-improvements
feat: offer to import youtube transcripts dynamically
2023-03-23 11:18:31 -04:00
Kristin Aoki
641a169e6f feat: upgrade flcc to 1.11.8.0 (#466) 2023-03-22 14:52:22 -04:00
connorhaugh
df5af3efd9 feat: tolerance Setting Widget (#286)
* feat: tolerance Setting Widget

* fix: tolerance position and percent summary
2023-03-22 14:31:02 -04:00
Kristin Aoki
16003a7f4a feat: move explanation to main body of editor (#287) 2023-03-22 09:36:01 -04:00
Maxim Beder
6c8fca8113 test: add tests for VideoSettingsModal 2023-03-20 15:26:45 +01:00
Maxim Beder
363df38b1f feat: offer to import youtube transcripts dynamically
Before this commit, the popup message which offers to import transcripts
from YouTube would only appear after saving the video settings, and then
reopenning the editor.

With this commit, the popup appears dynamically, i.e. whenever a URL is
changed to a YouTube one, certain validations and check take place,
after which, if possible to do so, user will be offered to import
transcripts from the YouTube video.
2023-03-20 14:04:38 +01:00
kenclary
25e254bbfb chore: update frontend-lib-content-components to 1.117.1. (#465) 2023-03-16 14:46:56 -04:00
Raymond Zhou
da9cb6054c Revert "feat: update switch to Advanced Editor warning (#259)" (#282)
This reverts commit 4a24d25f22.
2023-03-16 13:44:41 -04:00
Kristin Aoki
fa14365d54 feat: update text areas to expandable text areas (#274) 2023-03-16 13:17:01 -04:00
kenclary
84b9dd7e88 Merge pull request #277 from jansenk/jkantor/video-public-allowed-gate
feat: don't show video sharing checkbox unless waffle from studio is active
2023-03-15 16:21:03 -04:00
jansenk
97d0a74fef feat: call video_features cms endpoint for waffle status 2023-03-15 14:39:15 -04:00
jansenk
a895c28c4c feat: hide checkbox when video share not enabled for course 2023-03-15 14:39:15 -04:00
connorhaugh
2dc42e6a46 fix: show answer attempts spacing (#276) 2023-03-14 12:29:25 -04:00
Raymond Zhou
56621ca575 feat: remove general and group feedback (#273) 2023-03-13 12:25:38 -04:00
Mashal Malik
2ea3efed4b Update transifex api from v2 to v3 (#264) 2023-03-13 12:25:12 -04:00
connorhaugh
18fd63ab69 feat: expanding complex text area (#257) 2023-03-13 09:21:17 -04:00
Jenkins
af0ddf532a chore(i18n): update translations 2023-03-12 17:32:39 -04:00
kenclary
b917586fd8 Merge pull request #268 from openedx/kenclary/TNL-10507-1
fix: ProblemEditor useEffect at beginning of component; message for block failed to load. TNL-10507
2023-03-10 18:19:25 -05:00
Ken Clary
55b1e41898 fix: ProblemEditor useEffect at beginning of component; message for block failed to load. TNL-10507 2023-03-10 15:01:39 -05:00
Jesper Hodge
0ce9e4dfd3 fix: answer button accessibility (#271) 2023-03-10 14:18:21 -05:00
kenclary
eaf76c8dee chore: update frontend-lib-content-components to 1.113.0. (#459) 2023-03-10 10:51:50 -05:00
kenclary
b4edfe0bcb Merge pull request #270 from jansenk/jkantor/video-public
feat: Add "allow sharing" checkbox to video editor
2023-03-09 14:28:56 -05:00
Ihor Romaniuk
5c0ca7b706 feat: replace hardcoded edx string with site_name from configs (#425)
* feat: replace hardcoded edx string with site_name from configs

* feat: add ability to obtain site name dynamically

* fix: localize overriding createPortal method
2023-03-09 13:38:22 -05:00
jansenk
4467590a65 test: code review 2023-03-09 13:08:09 -05:00
jansenk
2be52871aa test: update snapshot 2023-03-09 11:38:17 -05:00
jansenk
968f48c55a feat: add checkbox for public video sharing field 2023-03-09 11:38:17 -05:00
Jeremy Ristau
54d4d2cca2 Merge pull request #269 from openedx/maintainership-phase1
chore: add missing maintainership files
2023-03-09 10:22:27 -05:00
Jeremy Ristau
07a84bc133 chore: add CODEOWNERS file to repo, point to tnl
This is related to Maintainership Pilot expectations. This CODEOWNERS file will notify teaching-and-learning team members of PR submissions, but there are currently no additional branch protections related to this ownership.
2023-03-09 09:58:32 -05:00
Jeremy Ristau
7fc149b882 chore: add catalog-info file for Open edX Backstage
This file populates Backstage info for the Open edX community. It helps identify that tnl is the owner of this component. This is in relation to Maintainership OEP-55.
2023-03-09 09:53:39 -05:00
Raymond Zhou
e6b532c71e Feat allow not select feedback for only multi select problem type (#267) 2023-03-08 15:18:57 -05:00
Raymond Zhou
b0c1e4d754 feat: clear save failed status when closing error (#266) 2023-03-07 13:27:55 -05:00
Mashal Malik
530b247c33 refactor: remove unused tranisfex v2 url (#457) 2023-03-06 12:18:02 +05:00
Ihor Romaniuk
a5bc86e948 feat: replace hardcoded logo with logo from configs (#426) 2023-03-03 08:29:12 -05:00
Raymond Zhou
b84c9c006e feat: fix time between attempts label (#263) 2023-03-02 16:46:05 -05:00
Kristin Aoki
5d77dddaf6 feat: add labels and blockquotes to clear format (#261) 2023-03-02 11:43:49 -05:00
connorhaugh
9910937269 feat: flcc 1.109.2 (#456) 2023-03-02 10:48:29 -05:00
connorhaugh
77f030c3fe fix: remove reset widget from advnaced editor 2023-03-02 10:20:22 -05:00
connorhaugh
7a8a182d5a fix: explantion data parse (#260) 2023-03-02 09:20:37 -05:00
Raymond Zhou
4a24d25f22 feat: update switch to Advanced Editor warning (#259) 2023-03-01 16:06:49 -05:00
Raymond Zhou
493ef9026e feat: numeric input UI to allow only correct (#256) 2023-03-01 13:02:27 -05:00
0x29a
897c440f26 test: test the new message, update the snapshot 2023-03-01 17:15:54 +01:00
0x29a
5b543ea93e feat: show "Custom" instead of "Total" when the widget is collapsed 2023-03-01 17:15:41 +01:00
0x29a
0fa18e4199 feat: outline and align right the total label 2023-03-01 16:31:20 +01:00
Kristin Aoki
c65f60ec10 feat: refactor tinymce editor to sharedComponents (#255) 2023-02-28 16:37:52 -05:00
Raymond Zhou
e0c5573c8d feat: tinyMCE config changes (#253) 2023-02-27 13:48:04 -05:00
connorhaugh
1344c289df feat: update flcc (#453) 2023-02-24 11:41:11 -05:00
Feanil Patel
7f4111c12c Update standard workflow files. (#452)
* 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.

* 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.

* 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-24 10:44:48 -05:00
connorhaugh
3c3361c765 fix: file upload on safari (#254)
* fix: file upload on safari

* fix: lint fix
2023-02-24 10:40:56 -05:00
Feanil Patel
a184ac981c Update standard workflow files. (#252)
* 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.

* build: Creating 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.

* 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.

* build: Updating a missing workflow file `commitlint.yml`.

The .github/workflows/commitlint.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-24 10:40:43 -05:00
Kristin Aoki
76aae38d3a fix: check for if an answer changes to false (#250) 2023-02-23 10:02:22 -05:00
Raymond Zhou
f18353e5fc feat: fix initial advanced problem type olx (#251) 2023-02-22 17:59:27 -05:00
connorhaugh
316f6f2850 feat: reset card link works (#249) 2023-02-17 13:53:09 -05:00
Kristin Aoki
70c0fc6dcf fix: settings col width in advanced view (#233) 2023-02-15 16:37:55 -05:00
Raymond Zhou
6156798e02 feat: move solution tag inside problem type tag (#248) 2023-02-15 12:53:02 -05:00
Raymond Zhou
3f9fc513cf feat: remove Hints widget from advanced editor (#247) 2023-02-15 12:52:52 -05:00
connorhaugh
105fdea8ef feat: upgrade FLCC to 1.101.3 (#451) 2023-02-15 08:41:05 -05:00
connorhaugh
61c99b9b40 feat: add error boundary (#246)
* feat: add error boundary
2023-02-14 15:21:43 -05:00
Raymond Zhou
529ec8ddf2 feat: fix checkbox colors for feedback (#244) 2023-02-14 12:34:55 -05:00
connorhaugh
b4f1676acf feat: add feedback link (#245)
For Problem Editor Beta
2023-02-14 10:20:26 -05:00
connorhaugh
9d91e3f242 feat: update flcc to 1.99.3 (#449) 2023-02-13 12:58:00 -05:00
Kristin Aoki
eeaa0e3f68 fix: getGeneralFeedback selectedFeedback error (#243) 2023-02-10 14:54:56 -05:00
kenclary
0367ef776e Merge pull request #240 from openedx/kenclary/TNL-10433
fix: more correct parsing of settings, for scoring; use empty string instead of null for empty attempts. TNL-10433.
2023-02-10 12:01:10 -05:00
Raymond Zhou
eff3df7115 Feat allow singleselect to accept multiple correct answers (#241) 2023-02-10 11:31:52 -05:00
Kristin Aoki
a22ad54502 fix: update problem description in preview block (#242) 2023-02-10 11:00:49 -05:00
connorhaugh
fdcb3a5e7f feat: update FLCC to 1.99.0 (#447) 2023-02-10 10:22:48 -05:00
Ken Clary
38e262eee0 fix: more correct parsing of settings, for scoring; use empty string instead of null for empty attempts. TNL-10433. 2023-02-10 09:17:44 -05:00
connorhaugh
d69d3e1ce7 feat: Group, General Feedback Settings, Randomization
This Ticket adds three new settings widgets to the Problem Editor:
Randomization: This is a setting for advanced problems only which deals with python scripts.
General Feedback: This is feedback which is only applied to certain problem types for mass-adding feedback to incorrect problems.
Group Feedback: For certain problems, the user can provide specific feedback for a combination of specific answers.
2023-02-10 08:50:32 -05:00
kenclary
7c0309189f Merge pull request #238 from openedx/kenclary/TNL-10426
feat: multiple numericalresponse tags no longer special-cased against going to the advanced editor. TNL-10426.
2023-02-09 18:40:59 -05:00
Raymond Zhou
1282a72acf feat: green radio+checkbox only for valid Checker (#239) 2023-02-09 18:33:20 -05:00
Ken Clary
746cd7cc28 feat: multiple numericalresponse tags no longer special-cased against going to the advanced editor. TNL-10426. 2023-02-09 14:47:29 -05:00
Bilal Qamar
86974b76a9 Fixed broken "Pages and Resources" page (#446)
* fix: updated AppHeader call

* fix: AppHeader function signature changed to react component
2023-02-09 06:45:37 -05:00
Raymond Zhou
46427ee156 feat: make radio and checkbox green (#234) 2023-02-08 14:41:36 -05:00
Kristin Aoki
87aaa7f3ff fix: add empty answer to problem without answers (#235) 2023-02-07 20:04:16 -05:00
Kristin Aoki
835915750c feat: update frontend-lib-content-component 1.95.0 (#445) 2023-02-07 16:13:51 -05:00
Kristin Aoki
613b8d16ae feat: update question parser to preserve text structure (#232) 2023-02-07 14:31:41 -05:00
Raymond Zhou
7e8f9a2f0c feat: change title when problem type changes (#231) 2023-02-06 13:11:59 -05:00
kenclary
65b663bfc6 Merge pull request #229 from openedx/kenclary/TNL-10413
fix: correct question parsing/building after use of styling. TNL-10413.
2023-02-06 10:17:02 -05:00
Jenkins
fe8a125d1a chore(i18n): update translations 2023-02-05 16:32:36 -05:00
Ken Clary
ea6c2c6658 fix: correct question parsing/building after use of styling. TNL-10413. 2023-02-03 11:28:20 -05:00
Raymond Zhou
d978725c35 feat: react to OLX parser process number answers (#230) 2023-02-02 15:30:05 -05:00
Kristin Aoki
57dd03f40f feat: fix feedback box bugs (#227) 2023-02-02 13:51:58 -05:00
Kristin Aoki
796dd388f7 fix: selectTypeModal header z-index (#228) 2023-02-02 13:43:49 -05:00
Kristin Aoki
f82e572ad2 feat: update frontend-lib-content-components (#439) 2023-02-01 15:46:13 -05:00
Kristin Aoki
74b2b76beb fix: add check for question length for parser (#226) 2023-02-01 15:00:03 -05:00
kenclary
2f1072812d Merge pull request #224 from openedx/kenclary/TNL-10390
fix: correct css for text margins in question tinymce. TNL-10390.
2023-02-01 13:58:38 -05:00
Jesper Hodge
861b47b772 feat add olx solution support (#225)
This adds support for the tag in OLX and maps it to the description in the settings options on the ShowAnswer card.
https://2u-internal.atlassian.net/browse/TNL-10397
2023-02-01 13:28:14 -05:00
Ken Clary
b1201cdcef fix: correct css for text margins in question tinymce. TNL-10390. 2023-02-01 12:49:38 -05:00
Kristin Aoki
83d45a249a feat: add label button to question tinyMCE (#221) 2023-02-01 11:35:15 -05:00
Kristin Aoki
8aa03496fb feat: update frontend-content-components & paragon (#438) 2023-01-31 15:21:13 -05:00
kenclary
09d5ce35f3 Merge pull request #219 from openedx/kenclary/TNL-10395
fix: question field uses real placeholder instead of template. fixed blank question handling. TNL-10395, TNL-10411.
2023-01-31 13:31:36 -05:00
Kristin Aoki
787c4068f2 feat: add margin to prevent footer blocking content (#222) 2023-01-31 12:12:38 -05:00
Muhammad Abdullah Waheed
3c2c347bb9 Automate Browserlist DB Update (#357)
* feat: added cron github action to auto update brwoserlist DB periodically

* refactor: used a shared script to update broswerslist DB, create PR and automerge it
2023-01-31 17:40:26 +05:00
Ken Clary
80f2689cc2 fix: question field uses real placeholder instead of template. fixed blank question handling. TNL-10395, TNL-10411. 2023-01-30 19:06:53 -05:00
Jenkins
0d166288cc chore(i18n): update translations 2023-01-29 16:32:35 -05:00
kenclary
4a1bac3bdb Merge pull request #218 from openedx/TNL-10400
fix: give QuestionWidget Editor a minimum height. TNL-10400.
2023-01-27 10:37:04 -05:00
Ken Clary
84fe6605c2 fix: give QuestionWidget Editor a minimum height. TNL-10400. 2023-01-26 16:48:21 -05:00
kenclary
fa2387ae00 Merge pull request #217 from openedx/kenclary/TNL-10401
fix: multiple non-numeric problems of the same type should also route to the advanced editor. TNL-10401.
2023-01-26 15:57:21 -05:00
Ken Clary
3b9681618c fix: multiple non-numeric problems of the same type should also route to the advanced editor. TNL-10401. 2023-01-26 12:28:55 -05:00
Kristin Aoki
afec2865c0 fix: separate feedback onchange for each field (#214) 2023-01-26 09:48:43 -05:00
Bilal Qamar
f8954ef870 refactor: upgraded frontend-build version to v12
PR #322
2023-01-26 09:02:14 -03:00
Jesper Hodge
83acc741f5 fix remove problem placeholder answer text (#215)
* refactor: rename hook correctly

* fix: problem templates
2023-01-25 15:02:35 -05:00
Kristin Aoki
2d669cbe3e feat: update styling in advanced problem editor (#216) 2023-01-25 10:42:30 -05:00
Kristin Aoki
656e8f8568 feat: update answer helper text (#213) 2023-01-25 10:10:08 -05:00
Muhammad Adeel Tajamul
66afd4ddac fix: updated openedx discussion provider help text (#431)
Co-authored-by: adeel.tajamul <adeel.tajamul@arbisoft.com>
2023-01-25 07:42:29 +05:00
Kristin Aoki
a99eb8a44a feat: upgrade frontend-lib-content-components (#436) 2023-01-24 13:51:06 -05:00
Kristin Aoki
be6aca8e8e feat: add function to remove empty hints (#211) 2023-01-24 13:12:41 -05:00
Jesper Hodge
1a2f175989 fix: problem editor styling (#212)
* fix: test name

* fix: make horizontal paddings 24px

* fix: space between widgets

* fix: remove settings heading

* fix: remove button hover effects

* fix: font size

* fix: make buttons small

* fix: change theme

* fix: reset buttons

* refactor: add Button component

* fix: hints widget

* fix: hints widget

* fix: tooltip

* fix: make settings fixed width

* fix: modal heading

* fix: center header text

* fix: modal header

* fix: settings fonts

* fix: settings fonts

* fix: fonts

* fix: padding

* fix: alignments

* fix: package.json

* fix: package.json

* fix: lint
2023-01-24 13:00:38 -05:00
Kristin Aoki
77afb7465b feat: update onclick to close modal + top scroll (#207) 2023-01-24 11:34:55 -05:00
kenclary
b2981318b0 chore: update version of frontend-lib-content-components to 1.85.0. (#435) 2023-01-24 10:16:03 -05:00
Raymond Zhou
f135bd2b4a feat: align files with commit 5d52a28 and f9dff0 (#210)
This PR aims to fix the commit mistakes I made when trying to merge with a refactored fork. This will keep the changes I made in the refactor.
2023-01-24 09:43:01 -05:00
rayzhou-bit
acee24eaa7 Merge branch 'main' of https://github.com/openedx/frontend-lib-content-components 2023-01-23 15:42:18 -05:00
rayzhou-bit
b7c654399b fix: fix revert 2023-01-23 15:42:13 -05:00
rayzhou-bit
1557fabf9e Revert "Merge branch 'main' of github.com:rayzhou-bit/frontend-lib-content-components into rayzhou-bit-main"
This reverts commit f9dff0df85, reversing
changes made to 5d52a289dc.
2023-01-23 15:12:32 -05:00
rayzhou-bit
bafc3c8de8 Revert "feat: merge conflicts"
This reverts commit 73ec807dd3, reversing
changes made to 62cfecc456.
2023-01-23 14:51:21 -05:00
rayzhou-bit
73ec807dd3 feat: merge conflicts 2023-01-23 13:49:25 -05:00
rayzhou-bit
f9dff0df85 Merge branch 'main' of github.com:rayzhou-bit/frontend-lib-content-components into rayzhou-bit-main 2023-01-23 13:42:15 -05:00
kenclary
5d52a289dc Merge pull request #200 from openedx/kenclary/TNL-10332
fix: various style and UX fixes. TNL-10332.
2023-01-23 13:01:26 -05:00
Ken Clary
d3be3d4240 fix: Correct summary of number of attempts; new separator between attempts summary and points summary; hint text for both attempts and points settings; fixed some widget paddings; advanced problems do not show type setting, and type setting menu does not show advanced problems. TNL-10332. 2023-01-23 12:34:43 -05:00
Jenkins
5142f3afd4 chore(i18n): update translations 2023-01-22 16:32:35 -05:00
Jesper Hodge
5aca835a4b Fix problem editor margins and borders (#203)
* fix: fix border and allow customizing of tinymce style

* fix: make tinymce widget look like on figma

* fix: update settingsoptions card border

* fix: header typography

* fix: spacings

* chore: update snapshots

* Update src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/index.jsx

Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com>

* Update src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/index.jsx

Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com>

* Update src/editors/containers/ProblemEditor/components/EditProblemView/index.jsx

Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com>

* Update src/editors/containers/ProblemEditor/components/EditProblemView/QuestionWidget/index.jsx

Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com>

* Update src/editors/containers/ProblemEditor/components/EditProblemView/QuestionWidget/index.jsx

Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com>

* Update src/editors/containers/ProblemEditor/components/EditProblemView/QuestionWidget/index.jsx

Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com>

* fix: html and react problems in problem editor

* chore: update snapshots

* chore: apply pr suggestions

* chore: fix test coverage

* chore: fix lint

* chore: fix tests

* chore: fix lint

Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com>
2023-01-20 15:59:30 -05:00
Kristin Aoki
d6d3363866 feat: make problem select and preview a fixed size (#204) 2023-01-20 15:05:53 -05:00
Kristin Aoki
f08a662136 feat: remove drag and drop from advanced problems (#206)
Drag and drop V2 is still available in studio via the "Advanced" component.
2023-01-20 14:22:33 -05:00
Raymond Zhou
b7b3601337 feat: update FLCC to 1.81.0 (#432) 2023-01-20 11:55:58 -05:00
Raymond Zhou
9c4077f32d feat: set videoId to '' instead of null on load (#205) 2023-01-20 11:22:18 -05:00
rayzhou-bit
317cb48dbe feat: fix to updateDuration call 2023-01-20 05:44:22 -05:00
rayzhou-bit
62cfecc456 feat: fix input for updateDuration call 2023-01-19 16:25:08 -05:00
rayzhou-bit
f64d1bb127 feat: package-lock 2023-01-18 18:18:39 -05:00
rayzhou-bit
af94e15ffb feat: name changes 2023-01-18 18:08:07 -05:00
Kristin Aoki
5e037a7209 feat: change editor footer from sticky to fixed (#202) 2023-01-18 14:39:46 -05:00
Kristin Aoki
adb24ef9ea feat: change default question text (#199) 2023-01-18 12:50:26 -05:00
Jesper Hodge
9a8307001f add testability adr (#201)
* chore: hook ADR round 1

* chore: add adr number

* chore: revert changes that are not docs-related

* chore: revert changes

Co-authored-by: Ben Warzeski <bwarzeski@edx.org>
2023-01-18 11:44:50 -05:00
rayzhou-bit
34b7b3314c feat: revert to connect 2023-01-18 06:12:49 -05:00
Kristin Aoki
50e5ca86c6 feat: upgrade paragon and lib-content-components (#430) 2023-01-17 16:26:11 -05:00
Kristin Aoki
7d21a3d4c9 feat: change feedback and delete icons to outline variants (#198) 2023-01-17 15:41:11 -05:00
Jesper Hodge
b7c24d1e1a Fix answer box styling. TNL-10333 (#197)
* fix: use feedback icon with correct hover color

* fix: problem answer layout squishes delete button background

* fix: remove borders from textarea

* fix: textarea resize

* refactor: remove renderThing-antipattern in answer option

* fix: answer option feedback color

* fix: add second feedback box to all problem types

* refactor: move extra components out of answer option file

* fix: icon disappearing on hover when active

* fix: update snapshot

* fix: lint

* fix: add tests

* fix: add tests

* fix: snapshots

* Update src/editors/containers/ProblemEditor/components/EditProblemView/AnswerWidget/AnswerOption.jsx

Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com>

* fix: resolve discussions from PR

Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com>
2023-01-13 17:00:56 -05:00
connorhaugh
95ae45cce8 fix: update title on type select (#196)
* fix: update title on type select

* fix: lint fix

* fix: add test
2023-01-13 14:37:52 -05:00
Kristin Aoki
1a370c12d9 feat: update problem type titles + small ui fixes (#195) 2023-01-13 10:04:01 -05:00
connorhaugh
fe9a9a37e7 feat: upgrade to 1.76.0 (#429) 2023-01-12 15:43:22 -05:00
Kristin Aoki
990e35bdc2 feat: remove question box branding + menu (#192)
This PR address the console.log errors from the question box tinyMCE, removing the tinyMCE branding and menu.
2023-01-12 15:30:06 -05:00
connorhaugh
2a9851544e Fix: advanced problem template reference (#194)
* fix: correctly reference advanced problem templates

* fix: remove console log
2023-01-12 13:23:02 -05:00
Raymond Zhou
aad7a6b706 feat: video editor fix to disappearing transcript (#178)
* feat: video editor fix to disappearing transcript
2023-01-12 12:51:56 -05:00
Jesper Hodge
574c2cc76a fix: cannot open problem editor because of typeerror undefined (#193)
* fix: cannot open problem editor because of typeerror

* fix: snapshots
2023-01-12 12:25:18 -05:00
connorhaugh
1c5ab42ea6 feat: update flcc to 1.74.0 (#428) 2023-01-12 10:53:46 -05:00
kenclary
6d823e4e7c Merge pull request #187 from openedx/kenclary/TNL-10324
fix: match new frontend behavior with legacy behavior (zero problem attempts is zero attempts, null attempts is infinite); negative values disallowed and forced to zero. TNL-10324.
2023-01-12 10:40:47 -05:00
Ken Clary
390d620664 fix: match new frontend behavior with legacy behavior (zero problem attempts is zero attempts, null attempts is infinite); negative values disallowed and forced to zero. TNL-10324. 2023-01-12 10:31:13 -05:00
connorhaugh
6b2b5ac455 Update workflow 2023-01-12 09:56:59 -05:00
connorhaugh
70f5bb1080 build: pin semantic release to unblock pipeline (#191)
I saw that the release CI https://github.com/openedx/frontend-lib-content-components/actions/runs/3897027405/jobs/6654318273 was failing the release on [semantic-release]: node version >=18 is required. Found v16.19.0.

from https://github.com/semantic-release/semantic-release/releases/tag/v20.0.0 we learn that node v18 is now the minimum required version of node.

The version of semantic-release that runs in a repo is usually based on the relevant Github Acton workflow file for the release, defined in the repo itself.

I am pinning that version to 19.0.5 until the next node upgrade, as it seems we recently upgrade to node 16.
2023-01-12 09:31:31 -05:00
Kristin Aoki
5f5dc911da fix: change # destination to advance settings url (#189) 2023-01-12 09:22:37 -05:00
rayzhou-bit
e66863795c feat: tests argh 2023-01-11 20:14:03 -05:00
connorhaugh
9b2e284ee3 fix: remove test (#188) 2023-01-11 16:53:16 -05:00
Kristin Aoki
d23a790ad2 feat: allow feedback to copy when problem changed (#184) 2023-01-11 16:40:36 -05:00
connorhaugh
cf1daa3ba5 Feat add templates for default problems after problem select (#185)
https://2u-internal.atlassian.net/browse/TNL-10316 is the relevant bug.

Problems have default values when created using the select type page.
2023-01-11 14:26:46 -05:00
Jesper Hodge
2c6679fe06 Feat raw olx editing. TNL-10218 (#182)
* refactor: move CodeEditor to shared components and remove circular dependency

* feat: add code editor to problem editor

* fix: typo

* feat: add save function to raw olx editor and add highlighting

* feat: simplify and add tests to edit problem view

* feat: add tests to problem edit view

* fix: update raw editor tests

* fix: code editor tests

* fix: package-lock

* fix: lint
2023-01-11 14:23:06 -05:00
connorhaugh
f81b0ee925 docs: add period to module.config.js (#183) 2023-01-11 10:25:25 -05:00
kenclary
6a4ac3525f Merge pull request #180 from openedx/kenclary/TNL-10280
feat: confirmation dialog for closing any editor. TNL-10280.
2023-01-11 10:07:46 -05:00
Ken Clary
9ba0da04c3 feat: confirmation dialog for closing any editor. TNL-10280. 2023-01-11 09:58:43 -05:00
Kristin Aoki
af4cd55390 feat: unselect multiple choices type multi->single (#181) 2023-01-10 13:25:19 -05:00
connorhaugh
880d205cbb Feat: raw editor ingress and egress logic (#179)
* feat: conditional rendering of olx editor.

* fix: open the raw editor if advanced is chosen

* fix: add test fix

* feat: add button to switch visual->advanced

* fix: add tests + lint for visual->advanced button

* feat: revert to advanced if parser fails

* fix: improve coverage

* feat: add confirm dialog to switch

* fix: load settings with advanced

* fix: refactor + lint fix
2023-01-10 09:42:44 -05:00
Kristin Aoki
74fcbe426d feat: upgrade lib-content-components to 1.73.0 (#419) 2023-01-06 10:41:27 -05:00
Mehak Nasir
6a65826fd5 fix: group at subsection field added in redux state 2023-01-05 14:31:44 +05:00
Jesper Hodge
ad47bfacd4 docs: add fix for m1 macs to readme (#421) 2023-01-03 16:32:54 -05:00
rayzhou-bit
e946fb8711 feat: duration change first pass 2023-01-02 20:52:16 -05:00
Jenkins
9e9bac997b chore(i18n): update translations 2022-12-25 16:32:50 -05:00
Kristin Aoki
09bb1dab2b feat: add import transcripts from youtube (#176) 2022-12-23 10:54:07 -05:00
connorhaugh
014fbeac71 feat: release select type page (#418) 2022-12-23 09:22:14 -05:00
connorhaugh
2896393c53 feat: add problem type select
Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com>
Co-authored-by: Raymond Zhou <56318341+rayzhou-bit@users.noreply.github.com>
2022-12-22 16:52:21 -05:00
connorhaugh
0b214faeca feat: add problem editor to FLCC (#417) 2022-12-20 16:14:43 -05:00
connorhaugh
83cbac6270 feat: doc updates for problem editor release 2022-12-20 15:31:14 -05:00
connorhaugh
8dea72de99 feat:problem editor
Co-authored-by: Farhaan Bukhsh <farhaan@opencraft.com>
Co-authored-by: Navin Karkera <navin@disroot.org>
Co-authored-by: Kaustav Banerjee <kaustav@opencraft.com>
2022-12-20 14:52:20 -05:00
Zachary Hancock
abff65a11a fix: LTI providers should not be shown unless enabled (#416) 2022-12-19 10:46:04 -05:00
connorhaugh
6f82e87574 feat: make delete and info icons outlines (#150)
* feat: make delete and info icons outlines

* feat:upgrade paragon
2022-12-14 11:44:41 -05:00
Adolfo R. Brandes
2f6eed237a fix: Editors should support runtime configuration
Fetching settings directly via `process.env` circumvents the runtime
configuration mechanism.  Change the editor page to use `getConfig()`
instead.
2022-12-13 23:55:36 +00:00
Kristin Aoki
f85d86f796 fix: left and right alignment (#167) 2022-12-13 15:04:53 -05:00
Zubair Shakoor
128b112af7 fix: -t flag added in pull translation command (#142) 2022-12-13 13:23:24 -05:00
Kristin Aoki
7daa2c2dba fix: vertical spacing between items (#166) 2022-12-13 13:20:15 -05:00
Kristin Aoki
7253c9bba3 feat: upgrade lib-content-components 1.69.1 (#411) 2022-12-13 09:27:22 -05:00
Kristin Aoki
b5be6f441c fix: add check if field is cleared (#165) 2022-12-12 14:18:25 -05:00
Kristin Aoki
07202c0518 feat: separate video id and url fields into two (#164) 2022-12-12 10:55:32 -05:00
Jenkins
a84d3c09e8 chore(i18n): update translations 2022-12-11 16:27:30 -05:00
Raymond Zhou
f5e1f1cf6b feat: FLCC v1.68.0 (#407) 2022-12-09 11:37:31 -05:00
Raymond Zhou
bcb3c3f7fb feat: parseTranscript to work with all languages (#162)
* feat: parseTranscript to work with all languages
2022-12-09 11:05:50 -05:00
ayesha waris
8096a389da style: confirmation modal added for in-context discussion toggle (#404)
* style: confirmation modal added for in-context discussion toggle

* refactor: removed duplicate message id

* refactor: function moved to on line direct call
2022-12-09 18:40:21 +05:00
Raymond Zhou
cc61e2944c feat: header overlap content when scrolling down (#161)
* feat: header overlap content when scrolling down
2022-12-07 15:24:48 -05:00
kenclary
1a21850fc4 feat: upgrade lib-content-components to 1.66.3. (#405) 2022-12-07 11:58:26 -05:00
Kristin Aoki
01c3a42eb2 fix: transcript styling (#159) 2022-12-07 11:16:02 -05:00
kenclary
a15b894ec1 Merge pull request #160 from openedx/kenclary/TNL-10236
fix: editor title editing no longer tries to scale with input size. TNL-10236.
2022-12-07 11:10:21 -05:00
kenclary
014523731e Merge pull request #158 from openedx/kenclary/TNL-10235
fix: editor container titles are the same height whether displaying or editing. TNL-10235.
2022-12-07 11:01:38 -05:00
Ken Clary
f6574c6849 fix: editor title editing no longer tries to scale with input size. TNL-10236. 2022-12-07 10:31:29 -05:00
Ken Clary
3239810a7f fix: editor container titles are the same height whether displaying or editing. TNL-10235. 2022-12-07 10:05:33 -05:00
Kristin Aoki
efae5ecd4b feat: upgrade ib-content-components to 1.66.0 (#403) 2022-12-05 16:59:49 -05:00
Kristin Aoki
6368ccf5ac feat: show view license link at all levels (#157) 2022-12-05 12:43:14 -05:00
Jenkins
1e043325d6 chore(i18n): update translations 2022-12-04 16:32:30 -05:00
Kristin Aoki
0b199b1f5d feat: add black canvas when current thumbnail is deleted (#156) 2022-12-02 16:47:00 -05:00
Raymond Zhou
73150817ca feat: update paragon to v20.21.0 (#155) 2022-12-02 12:54:45 -05:00
Raymond Zhou
0bfce5594d feat: update paragon to v20.21.0 (#399) 2022-12-02 11:12:25 -05:00
connorhaugh
dbe2787785 feat: update flcc to 1.63.1 (#400) 2022-12-02 10:47:53 -05:00
connorhaugh
20e98319af feat: remove default background color for editors (#398) 2022-12-02 10:23:07 -05:00
Kristin Aoki
f824ef0551 fix: license styling (#154) 2022-12-01 15:14:44 -05:00
connorhaugh
35b58a42b5 feat: left align widget "add" buttons (#153) 2022-12-01 12:20:29 -05:00
Kristin Aoki
6a2bafb402 fix: font/icon size and color (#152) 2022-11-30 15:31:39 -05:00
connorhaugh
e70800543a feat: increase spacing between video settings (#149) 2022-11-30 14:12:03 -05:00
kenclary
1360994fc5 Merge pull request #151 from edx/kenclary/TNL-10240
fix: correct various strings, including making them sentence-case. TNL-10240.
2022-11-30 12:45:04 -05:00
Ken Clary
c4a7b97b63 fix: correct various strings, including making them sentence-case. TNL-10240. 2022-11-30 12:36:42 -05:00
Abdullah Waheed
2063049747 feat: added new translations in Makefile and updated all the translations 2022-11-30 13:30:22 +00:00
edX requirements bot
a7def9ce25 fix: -t flag added in pull translation command (#393) 2022-11-30 16:44:21 +05:00
Kristin Aoki
2418207149 feat: bump lib-content-componets to 1.61.0 (#397) 2022-11-29 16:34:42 -05:00
Kristin Aoki
7a356175e7 feat: update onBlur to set state to default values (#148) 2022-11-29 15:23:14 -05:00
Kristin Aoki
5da5967e97 feat: update lib-content-componets to 1.60.1 (#395) 2022-11-29 15:10:40 -05:00
Kristin Aoki
f38ae87c95 fix: length error on undefined fallback videos (#147) 2022-11-29 12:44:56 -05:00
Jenkins
45b2bf5b13 chore(i18n): update translations 2022-11-27 16:32:27 -05:00
ayesha waris
7527f6c764 Style: Toggle remains Disabled and Link to instructor dashboard show on Disabled Cohorts (#375)
* style: on disabled cohorts toggle remains disabled and link to instructor dashboard shows

* fix: test cases fixed

Co-authored-by: Mehak Nasir <mehaknasir94@gmail.com>
2022-11-21 14:41:40 +05:00
Ghassan Maslamani
bdfa1fdeb3 fix: force studio url to reload if changed
This chagne make it possible if this module was loaded **then**
  the configuration for studio url is changed, then it will pick
  the last value.

  More context overhangio/tutor-mfe/issues/86
2022-11-18 13:49:16 +00:00
Raymond Zhou
79f58cc8d0 feat: update to flcc 1.60 (#392) 2022-11-17 12:25:03 -05:00
Jeremy Ristau
08b5475548 feat: add CODEOWNERS file
feat: add CODEOWNERS file
2022-11-17 11:48:04 -05:00
Jeremy Ristau
f00f6174ac feat: add CODEOWNERS file
The repo should have a CODEOWNERS file, but this effort is specifically to help test a need to make an edx-platform file notify T&L when changes are made.  We are doing the testing on this edx repo that we own to minimize the churn and impact on edx-platform.

The scope of this effort includes:
# Create a CODEOWNERS file in this repo that calls out a single file as owned by a team.
# Submit a no-change PR to that file and ensure the team is notified
# Submit a no-change PR to another file in the repo and ensure the team is NOT notified
# Update the CODEOWNERS file to have T&L team as owners of the whole repo, instead of just one file (long term desired state)
2022-11-17 10:29:16 -05:00
Adolfo R. Brandes
437d0a37a9 docs: Document current feature-set of this MFE
This updates the README to include brief documentation on the purpose of
this MFE, the main features it provides, as well as their configuration
and external requirements.
2022-11-17 14:13:23 +00:00
Saad Yousaf
0e24a0767b fix: show Zoom settings when pii sharing is enabled and make launch email optional (#387)
Co-authored-by: Mehak Nasir <mehaknasir94@gmail.com>
2022-11-16 13:14:16 +05:00
Raymond Zhou
6c574ac18e feat: duration entree features (#143) 2022-11-15 16:22:29 -05:00
connorhaugh
91abf56977 feat: upgrade flcc to 1.58.0 (#390) 2022-11-15 13:31:15 -05:00
connorhaugh
ea50afc165 feat: update readme
adding this messaging to improve quality and trigger a release.
2022-11-15 12:17:30 -05:00
connorhaugh
3506db7c14 Feat improve transcript flow (#141)
https://2u-internal.atlassian.net/browse/TNL-10199
Rewrite of Transcripts widget to improve flow.
2022-11-15 12:03:04 -05:00
Kristin Aoki
f0734d86db feat: upgrade frontend-lib-components to 1.57.0 (#388) 2022-11-15 09:27:46 -05:00
Kristin Aoki
8eab620b65 feat: auto-resize width of input and allow save onBlur (#144) 2022-11-14 13:24:11 -05:00
Ahtisham Shahid
3581d633c1 Revert "fix: show Zoom settings when pii sharing is enabled and make launch email optional (#380)" (#386)
This reverts commit b8895bef33.
2022-11-11 21:25:41 +05:00
Saad Yousaf
b8895bef33 fix: show Zoom settings when pii sharing is enabled and make launch email optional (#380)
Co-authored-by: Mehak Nasir <mehaknasir94@gmail.com>
2022-11-11 18:08:26 +05:00
Kristin Aoki
89d0d12559 feat: bump upgrade of flcc to 1.56.1 (#385) 2022-11-10 09:35:09 -05:00
Kristin Aoki
af6e21e1fe fix: non-blocking UI bugs for video settings (#140) 2022-11-09 12:32:36 -05:00
Abderraouf Mehdi Bouhali
34fe291268 fix(rtl): mirror legacy page card arrow 2022-11-07 16:03:36 +00:00
Jenkins
4b1e292e1c chore(i18n): update translations 2022-11-06 16:32:32 -05:00
Raymond Zhou
b4b31794af feat: allow license library content edit (#139)
* feat: allow license library content edit
2022-11-03 19:58:22 -04:00
Kristin Aoki
90eb6fd0c3 feat: upgrade frontend-lib-content-components to 1.55.0 (#379) 2022-11-03 19:05:20 -04:00
kenclary
5f5250fd2c Merge pull request #131 from edx/kenclary/TNL-9823
feat: duration widget for video settings. TNL-9823.
2022-11-03 18:44:12 -04:00
Kristin Aoki
4187f6a884 feat: remove thumbnail widget from content libraries (#138) 2022-11-03 18:23:34 -04:00
Kristin Aoki
e5932ced27 feat: remove handout widget for content libraries (#137) 2022-11-03 18:16:04 -04:00
Ken Clary
a4f0a8f162 feat: duration widget for video settings. TNL-9823. 2022-11-03 17:55:05 -04:00
Kristin Aoki
50da8a0f0b feat: upgrade flcc to 1.52.0 and paragon to 20.18.0 (#377) 2022-11-02 11:26:46 -04:00
Raymond Zhou
79ae64b562 feat: license widget (#132) 2022-11-02 10:41:40 -04:00
Awais Ansari
7dcd328f2e fix: add . to helper message 2022-11-01 17:39:01 +05:00
Awais Ansari
e2d66cc605 fix: update helper text for bigBlueButton free plan 2022-11-01 17:39:01 +05:00
kenclary
f5fc721b3b feat: update lib-content-components to 1.51.2. TNL-10183. (#371) 2022-10-27 14:46:37 -04:00
kenclary
9c397d8802 Merge pull request #136 from edx/kenclary/TNL-10183
fix: filter for images in a null-safe/undefined-safe way. Fixes TNL-10183.
2022-10-27 10:52:40 -04:00
Ken Clary
c89ad83ed5 fix: filter for images in a null-safe/undefined-safe way. Fixes TNL-10183. 2022-10-26 20:32:52 -04:00
connorhaugh
bfb4de6b1a Fix: temp remove video preview text from settings editor (#134)
* fix: remove preview

* fix: unrelated remove removed fetchImages
2022-10-25 11:44:39 -04:00
Kristin Aoki
c4bbb6fa70 feat: update frontend-lib-content-components to 1.51.1 2022-10-25 11:10:20 -04:00
Kristin Aoki
ca5846f1f6 fix: text editor save to use assets array instead of object 2022-10-25 10:42:26 -04:00
Kristin Aoki
8e55081ce1 feat: revert selection.url change and replaced with getting the relative path substring from the absolute url 2022-10-24 16:49:47 -04:00
Kristin Aoki
e6101ed3ac feat: update setAssetToStaticUrl to include all assets 2022-10-24 13:44:33 -04:00
Muhammad Adeel Tajamul
748aee2cff fix: added bbb learn more env variable (#365)
Co-authored-by: adeel.tajamul <adeel.tajamul@arbisoft.com>
2022-10-20 17:31:14 +05:00
Kristin Aoki
31473d3f49 feat: update lib-content-components to 1.49.0 2022-10-19 15:30:18 -04:00
Kristin Aoki
cb01ff17a0 feat: add handout widget 2022-10-19 12:17:59 -04:00
Kristin Aoki
8a2c337170 feat: update edx packages: pargon, frontend-platform,browserslist-config (#129) 2022-10-18 12:12:38 -04:00
Kristin Aoki
4de727791a feat: update frontend-lib-content-components to 1.48.0 and upgrades paragon to 20.13.0 2022-10-17 15:34:09 -04:00
Kristin Aoki
84f35dad40 feat: add automatic thumbnail resampling for thumbnail widget 2022-10-13 15:07:08 -04:00
Kristin Aoki
e9a123c16b feat: limit xblock title display 2022-10-13 12:44:56 -04:00
Zachary Hancock
d1d04d5585 feat: configure lti providers on exam settings modal (#363) 2022-10-13 09:22:36 -04:00
Raymond Zhou
6f41a14012 feat: update FLCC (#362) 2022-10-12 16:02:05 -04:00
Kristin Aoki
36576903ea feat: thumbnail widget 2022-10-12 15:42:38 -04:00
Raymond Zhou
b035725344 feat: bump version (#127) 2022-10-12 15:11:29 -04:00
rayzhou-bit
72aa2dbe92 feat: bump version 2022-10-12 15:00:16 -04:00
Raymond Zhou
d2f07045f0 Feat video source integration (#125)
* feat: video source integration

Co-authored-by: KristinAoki <kaoki@2u.com>
2022-10-12 12:38:44 -04:00
kenclary
a7abab1236 Convert video settings from xblock metadata into the redux store. In-progress draft. TNL-10009. (#119)
* feat: Convert video settings from xblock metadata into the redux store. In-progress draft. TNL-10009.

Co-authored-by: rayzhou-bit <rzhou@2u.com>
2022-10-04 14:59:22 -04:00
Raymond Zhou
cc3a2d8b85 feat: videosource to backend (#118)
* feat: videosource to backend
2022-09-30 11:00:06 -04:00
Kristin Aoki
79ceaca8cc feat: update UI for video source widget (#120) 2022-09-28 11:34:56 -04:00
connorhaugh
45215ba504 Feat: full transcript widget (#117) 2022-09-27 14:09:29 -04:00
Kristin Aoki
ff636837cf feat: transcript parent widget component 2022-09-14 11:07:20 -04:00
connorhaugh
3f303a718d feat: unescape alphanumerics in code Editor (#112)
* feat: unescape alphanumerics in code Editor

* fix: replace disable with not render
2022-09-09 11:09:53 -04:00
Kristin Aoki
03a609ea98 feat: allow .ico image file types 2022-09-08 12:36:34 -04:00
Raymond Zhou
54d773a19a Feat shared widget componentries and layout (#107) 2022-09-07 12:22:27 -04:00
connorhaugh
720b41193f fix: intermittent raw loading error (#109)
As sometimes the html components are rendered downstream before the block is loaded, we need to handle the case of no block value being provided to the raw editor at the time of first render. Subsequent thunk actions will trigger re-renders to display the block.
2022-09-01 14:35:44 -04:00
Kristin Aoki
e5ea0a096c feat: change image absolute urls to relative urls 2022-08-31 12:03:07 -04:00
Kristin Aoki
2d427da80f feat: add tinyMCE functionality for drag resizing of images 2022-08-31 09:18:36 -04:00
Kristin Aoki
4e69fffbef feat: remove the ability to use image tools for content libraries 2022-08-30 16:40:17 -04:00
Kristin Aoki
36380edce4 feat: add codeMirror lineWrapping extension 2022-08-29 09:39:46 -04:00
Kristin Aoki
2b49304ecc feat: change static url to asset url in editor 2022-08-24 12:53:18 -04:00
Raymond Zhou
09110ec0b0 feat: run onImgLoad even on broken images (#102)
* feat: run onImgLoad even on broken images
2022-08-23 06:00:46 -04:00
connorhaugh
564dcb8ebc feat: improve raw HTML editing Experince. (#101)
* feat: add contents

* feat: add codemirror support to raw HTML editing

* feat: add test coverage

* fix: error

* fix: update codeeditor file path

* fix: update messages
2022-08-22 15:19:21 -04:00
Kristin Aoki
617f316f37 feat: allow relative urls for assets 2022-08-18 09:04:44 -04:00
Farhaan Bukhsh
405c3cf7e3 chore: Update the Readme for project (#98)
Signed-off-by: Farhaan Bukhsh <farhaan@opencraft.com>

Signed-off-by: Farhaan Bukhsh <farhaan@opencraft.com>
2022-08-17 11:13:40 -04:00
Kristin Aoki
d68c357a86 feat: resolve console errors regarding skin.css 2022-08-15 11:26:39 -04:00
Kristin Aoki
f86e1fe97e feat: update editor text to match studio styling 2022-08-12 10:47:11 -04:00
Raymond Zhou
476c450e6c Feat updates to code block button (#93)
* feat: updates to code block button

* feat: updates to code block button
2022-08-10 12:59:03 -04:00
Kristin Aoki
1b180de468 feat: add altText and isDecorative persistence for image editing 2022-08-10 09:17:35 -04:00
Kristin Aoki
d739bcbdb5 feat: Prevent image uploads larger than 10 MB and add spinner 2022-08-08 15:44:59 -04:00
Kristin Aoki
9b23731acc feat: Add functionality to resize image based on percentage (#94)
* feat: add image resizing with percents
2022-08-05 12:13:57 -04:00
Kristin Aoki
3821378dc1 Merge pull request #92 from edx/KristinAoki/tinymce-underline
fix: added underline option to toolbar. TNL-10003
2022-08-01 10:29:21 -04:00
KristinAoki
6be7433567 Merge branch 'KristinAoki/tinymce-underline' of https://github.com/edx/frontend-lib-content-components into KristinAoki/tinymce-underline 2022-08-01 09:15:35 -04:00
KristinAoki
cc7e502011 fix: added underline option to toolbar. TNL-10003 2022-08-01 09:11:01 -04:00
KristinAoki
a918da46c2 Add underline option to editor toolbar 2022-07-29 12:02:08 -04:00
Raymond Zhou
80dfc6ba15 feat: www gallery raw selection (#88)
* feat: www gallery raw selection
2022-07-22 10:58:55 -04:00
connorhaugh
224720c32e feat: reorganize dependancies (#91) 2022-07-11 16:19:31 -04:00
connorhaugh
9829a5d4ef feat: No - OP (#90) 2022-07-07 08:47:56 -04:00
connorhaugh
2473c9a875 chore: upgrade paragon dep (#89)
* chore: upgrade paragon dep

* fix: eslint config
2022-07-05 09:08:15 -04:00
Raymond Zhou
b047f7a2a8 feat: raw html editor (#86)
raw html editor
2022-06-28 14:25:09 -04:00
connorhaugh
b2fec70702 feat: swap relative Urls bool (#85) 2022-06-10 10:46:34 -04:00
connorhaugh
728dc58ac4 fix: Remove addition to URLs in text editor (#84) 2022-06-09 09:43:23 -04:00
connorhaugh
81fc4fca6f docs: adopt ADR 4 (#79) 2022-06-09 09:41:56 -04:00
connorhaugh
cc4e19cd2a fix: redirect to correct learning context (#83)
For https://2u-internal.atlassian.net/browse/TNL-9955
there are multiple instantiations of the text editor in different contexts, so we need to handle them upfront to not break either experience flow” or something along those lines…
2022-06-09 09:41:31 -04:00
Raymond Zhou
ca9f788838 feat: toolbar stays visible when scrolling (#82) 2022-05-27 12:40:20 -04:00
kenclary
0e523feb09 Merge pull request #81 from edx/kenclary/TNL-9943
fix: allow style tags inside html body, to match old editor behavior. TNL-9943.
2022-05-26 13:44:41 -04:00
kenclary
c02bb9df7f Merge branch 'main' into kenclary/TNL-9943 2022-05-25 17:23:07 -04:00
Ken Clary
5922e25b3d fix: allow style tags inside html body, to match old editor behavior. TNL-9943. 2022-05-25 15:15:43 -04:00
connorhaugh
3b859734fd feat: add simple code block and blockquote buttons (#80)
* feat: add simple code block and blockquote buttons

* fix: readaad context toolbar
2022-05-25 13:58:11 -04:00
connorhaugh
a74b2f2272 docs: V2 Content Editors ADR (#72)
This PR adds an overarching ADR for the V2 Content Editors framework, as well as several other, smaller, ADRs related to architectural abstractions.
2022-05-19 10:05:52 -04:00
connorhaugh
a3c50b2723 feat: allow all html tags (#77)
* feat: allow all html tags.
2022-05-18 13:24:13 -04:00
connorhaugh
94009e6ed7 fix: delete z index css (#78)
* fix: delete z index css

* fix: remove from index.css
2022-05-17 13:50:41 -04:00
connorhaugh
5aea213b8c feat: add autocreate new xblock (#67)
This PR adds an automated script for generating the boilerplate code for adding a new xblock editor. As well as documentation for how to do so.
2022-05-16 16:14:18 -04:00
kenclary
0d51b45636 Merge pull request #75 from edx/kenclary/TNL-9879
chore: npm update, using node 16 / npm 8. TNL-9879.
2022-05-15 10:18:28 -04:00
Ken Clary
d74f2b8ba9 chore: npm update, using node 16 / npm 8. TNL-9879. 2022-05-15 09:57:10 -04:00
Raymond Zhou
76dcd1a920 Feat alert users with feedback instead of disabling next/save buttons (#68)
* feat: implemented user feedback ErrorAlerts
2022-05-13 15:23:42 -04:00
Jawayria
b5480beaf8 feat: Add package-lock file version check (#73) 2022-05-13 14:55:29 -04:00
Tim McCormack
18e3012462 fix: Fix pull_translations by using correct CLI flag for languages (#74)
Docs: https://developers.transifex.com/docs/using-the-client

Apparently this CLI option changed from singular to plural at some point.
2022-05-13 13:03:26 -04:00
Ben Warzeski
564b953860 feat: video skeleton hooks (#65)
* feat: video skeleton hooks

* fix: lint

* Update src/editors/containers/VideoEditor/components/VideoSettingsModal/components/CollapsibleFormWidget.jsx

Co-authored-by: connorhaugh <49422820+connorhaugh@users.noreply.github.com>

Co-authored-by: connorhaugh <49422820+connorhaugh@users.noreply.github.com>
2022-05-09 14:23:21 -04:00
bszabo
964f00e563 Merge pull request #71 from edx/TNL-9888-text-editor-ADR
docs: ADR for text editor decisions May 2022
2022-05-06 11:39:56 -04:00
Bernard Szabo
46458b0f58 docs: TNL-9888 ADR for text editor decisions May 2022
Mostly notes on how to use TinyMCE to meet product requirements
Includes pull request feedback
Co-authored-by: Ben Warzeski <bwarzeski@2u.com>
2022-05-06 11:38:59 -04:00
Bernard Szabo
da6bdad9f0 docs: TNL-9888 ADR for text editor decisions May 2022
Mostly notes on how to use TinyMCE to meet product requirements
Includes pull request feedback
Co-authored-by: Ben Warzeski <bwarzeski@2u.com>
2022-05-06 11:24:18 -04:00
kenclary
121f28c535 Merge pull request #70 from edx/kenclary/TNL-9876
fix: code plugin uses 'HTML' label instead of icon. Fixes TNL-9876.
2022-05-04 18:25:12 -04:00
Ken Clary
91be5db424 fix: code plugin uses 'HTML' label instead of icon. Fixes TNL-9876. 2022-05-04 16:50:07 -04:00
Bernard Szabo
7b6bd31475 docs: fix typo and clarify no feature loss requirement
per Ray Zhou's PR feedback
2022-05-04 15:24:13 -04:00
Raymond Zhou
51f89bdc1e feat: The X Button in the Top Right Doesn't do anything. (#66)
* fix: tests

* fix: onClose test case
2022-05-04 14:20:23 -04:00
Bernard Szabo
5920096306 docs: ADR for text editor decisions May 2022
Mostly how to use and extended tinyMCE
2022-05-04 10:52:44 -04:00
connorhaugh
0d4688ce75 feat: remove codesample add code plugin (#64) 2022-04-19 12:53:33 -04:00
connorhaugh
081129b639 feat: no-op commit update readme (#63)
this is for the release to stage.
2022-04-19 11:54:25 -04:00
Raymond Zhou
5200897e1b Fix change to go back to 'fake' modal (#62)
* fix: rebase

* fix: tests

* fix: remove broken code button

* fix: test case with iff
2022-04-19 11:25:01 -04:00
kenclary
be12d11027 Merge pull request #61 from edx/kenclary/TNL-9874
fix: rearrange and add several tinymce toolbar items. Addresses TNL-9874.
2022-04-18 16:43:00 -04:00
Ken Clary
1999041cdf fix: rearrange and add several tinymce toolbar items. Addresses TNL-9874. 2022-04-18 15:37:47 -04:00
Julia Eskew
51558fd17c Add events sent to Segment for the save and cancel clicks for content editors. (#44)
* feat: Add events sent to Segment for the save and cancel clicks for a content editor.

Co-authored-by: rayzhou-bit <rzhou@edx.org>
2022-04-18 13:44:27 -04:00
kenclary
3620cac421 Merge pull request #60 from edx/kclary/TNL-9855
fix: enable ordered and unordered lists in text editor. Fixes TNL-9855.
2022-04-14 16:05:04 -04:00
Ken Clary
24baf8cbeb fix: enable ordered and unordered lists in text editor. Fixes TNL-9855. 2022-04-14 15:20:31 -04:00
Ben Warzeski
cb1c00bf3c Feat: Video skeleton (#58)
* pt1

* feat: video skeleton

* fix: update tests

* chore: update snapshots and linting

* fix: fix image context button

* feat: re-usable editor pattern

* fix: css and bad hook
2022-04-14 15:01:04 -04:00
bszabo
0edee6b4e0 Merge pull request #57 from edx/TNL-9804-make-small-code-stewardship-changes-to-frontend-lib-content-components
Tnl 9804 make small code stewardship changes to frontend lib content components
2022-04-11 18:12:19 -04:00
Bernard Szabo
0d60cd97a0 refactor: Fix footer aria descriptions
'screensaver' in Aria description messages changed to 'screen reader'
2022-04-11 16:33:19 -04:00
Raymond Zhou
553e4d8c04 fix: editor has double scrollbars (#59) 2022-04-11 12:26:39 -04:00
Bernard Szabo
48fcfb0e00 refactor: Preserve button default messages
description for aria labels may explicitly reference intended screensaver use, but label names and ids should remain unchanged
2022-04-08 16:55:14 -04:00
connorhaugh
33b2c6a660 feat: image context toolbar (#55)
Note: this removes the crop and rotate functionality from the toolbar, as it requires an image_proxy server or tinymce cloud. https://www.tiny.cloud/docs-4x/plugins/imagetools/#imagetools_proxy. We also need to create a follow up ticket to handle right click behavior.
This is that follow up ticket
2022-04-08 13:23:42 -04:00
Raymond Zhou
ef6ea6b617 fix: saving block title (#50)
* fix: saving block title

* fix: ben's suggestions
2022-04-08 12:45:49 -04:00
Bernard Szabo
d79ee29b96 refactor: consistent naming and default message for saveButton label
Prior to this change Aria message and default message were different
2022-04-07 16:12:13 -04:00
Bernard Szabo
26c0c78660 refactor: use consistent ordering for header/footer attributes 2022-04-07 16:12:13 -04:00
kenclary
bc3ef37dcf Merge pull request #53 from edx/kenclary/TNL-9832
fix: remove spurious hard-coded height for img-settings-form-container class. Fixes TNL-9832.
2022-04-07 15:49:06 -04:00
Ken Clary
e3236e9d95 fix: remove spurious hard-coded height for img-settings-form-container class. Fixes TNL-9832. 2022-04-07 15:44:47 -04:00
connorhaugh
c817e17d8a fix: update texteditor spacing (#49)
footer is now locked to bottom of page, and that text editor content scrolls, and that this works on resize of page.
2022-04-07 14:49:15 -04:00
Raymond Zhou
8104aa3152 fix: load block title (#51) 2022-04-07 12:47:35 -04:00
connorhaugh
c3d9109211 fix: remove merge artifiact (#48)
For repo health
2022-04-06 10:50:08 -04:00
Raymond Zhou
45758612a4 feat: empty gallery (#46)
Adds a new option to the behavior for when the gallery has no images in it.
2022-04-05 11:43:40 -04:00
connorhaugh
049b6a9211 Fix: release ci (#47)
* feat: add capabilities

* chore: more tests

* fix: use correct hook source for getDispatch

* fix: fix fetchImages data contract

* fix: make onClose method a callback for ImageUploadModal

* chore: lint and test updates

* chore: clean up propType warning

* fix: upload of file

* fix: error notifcations

* fix: improve test coverage

* fix: lint fixes

* fix: lint fix

* rebase: stept 1

* rebase: step 2

* fix: use correct hook source for getDispatch

* rebase: step 3

* rebase: step 4

* chore: clean up propType warning

* fix: upload of file

* rebase: step 5

* fix: improve test coverage

* fix: lint fixes

* fix: release CI

Co-authored-by: Ben Warzeski <bwarzeski@edx.org>
2022-04-04 09:17:34 -04:00
connorhaugh
fd35c1cb18 Feat: Add Request Alerts and upload file (#43)
Fixes to Upload data type, as well as adding in of two error alerts for upload and fetch.
Co-authored-by: Ben Warzeski <bwarzeski@edx.org>
Co-authored-by: Raymond Zhou <56318341+rayzhou-bit@users.noreply.github.com
2022-04-04 08:33:31 -04:00
Raymond Zhou
28516a0389 fix: text editor save (#45)
* fix: text editor save

* fix: update snapshot
2022-04-01 17:01:12 -04:00
Raymond Zhou
dca18b9b97 chore: i18n complete (#37)
* chore: i18n
2022-03-31 16:14:29 -04:00
Ben Warzeski
0f87a61639 feat: Select img api (#41)
* feat: add capabilities

* chore: more tests

* fix: use correct hook source for getDispatch

* fix: fix fetchImages data contract

* fix: make onClose method a callback for ImageUploadModal

* chore: lint and test updates

* chore: clean up propType warning

Co-authored-by: connorhaugh <chaugh21@amherst.edu>
2022-03-30 15:13:19 -04:00
Ben Warzeski
1a5497a5ae Feat select image modal (#38)
* feat: select image modal

* chore: fix module config
2022-03-24 16:16:38 -04:00
Ben Warzeski
09e9d865c2 Chore: Test coverage hunt (#36)
* chore: add brand mocking in gallery view

* feat: dev gallery app

* chore: link mock block ids to real block type api

* feat: image settings page features

* chore: more tests

* chore: keystore util and more testing

* chore: more tests

* chore: re-install lint plugin...

* chore: lint fixes

* chore: moar tests

* chore: remove brand from module.config and link gallery to edx.org brand
2022-03-24 11:15:32 -04:00
Ben Warzeski
284601d6d2 feat: image dimension lock logic update (#34) 2022-03-22 10:03:26 -04:00
Ben Warzeski
3b8a7780ac I18n example (#33)
* feat: i18n pt 1

* fix: prevent float calculations when updating dimensions
2022-03-17 14:08:46 -04:00
Ben Warzeski
a79da4cb2d feat: useState test util (#31) 2022-03-16 11:27:08 -04:00
Jawayria
9e84e0ecf0 fix: update dependencies (#32)
* fix: update dependencies

Co-authored-by: M Umar Khan <umar.khan@arbisoft.com>
2022-03-16 09:45:35 -04:00
Ben Warzeski
32e4d5f7a1 feat: Image settings feature and design completeness (#30)
* feat: devgallery api mode

* feat: dev gallery app

* chore: link mock block ids to real block type api

* feat: image settings page features

* fix: update tests

* fix: console message cleanup

* fix: test fixes from code walkthrough with ray
2022-03-15 16:32:07 -04:00
connorhaugh
4ae2d1230b feat: insert images into text editor html (#29)
This work adds the functionality that when an image is selected ineither the select image step of the image upload modal, or by using the toolbar inside tinymce, the requisite image is loaded into the settings page, and on the click of the save button, it is inserted into tinymce html.
2022-03-15 10:53:56 -04:00
connorhaugh
5258e93972 Test add requests redux tests (#24)
Add redux tests as well as get save functionality working.
2022-03-07 19:43:46 -05:00
connorhaugh
c4cd0c44ce test: update editor-level tests (#26)
To complete https://openedx.atlassian.net/browse/TNL-9601
2022-03-07 15:03:13 -05:00
Ben Warzeski
ac0d261e89 Gallery app (#27)
* feat: devgallery api mode

* chore: update react version

* feat: dev gallery app

* chore: fix component tests

* chore: lint fixes

* chore: link mock block ids to real block type api
2022-03-07 13:35:28 -05:00
Raymond Zhou
6f0f6296e4 test: cms api tests + extra lint (#25) 2022-03-01 11:32:03 -05:00
Ben Warzeski
9c9d3c8fdf feat: image upload skeleton (#22) 2022-03-01 11:17:03 -05:00
Raymond Zhou
f3d80995c5 test: cms urls (#23) 2022-02-25 19:24:05 -05:00
connorhaugh
7ccba63a85 test: add TextEditor Tests (#21) 2022-02-25 15:06:12 -05:00
Raymond Zhou
042246be86 Test: editor header component (#20)
* test: header tests start

* test: EditableHeader test ready for review 1

* test: editor header tests complete

* test: fixing up nits

* test: ben's corrections
2022-02-25 12:15:13 -05:00
Ben Warzeski
1a1900f213 feat: redux tests pt 1 (#19)
* feat: redux tests pt 1

* chore: add app thunkAction tests

* chore: resolve lint issues

* Update src/editors/data/redux/app/reducer.test.js

Co-authored-by: connorhaugh <49422820+connorhaugh@users.noreply.github.com>

Co-authored-by: connorhaugh <49422820+connorhaugh@users.noreply.github.com>
2022-02-24 16:59:30 -05:00
Ben Warzeski
2b0346fe84 chore: add tests for EditorHeader hooks (#18) 2022-02-23 11:55:53 -05:00
connorhaugh
6ca93a7297 test: add EditorFooter tests (#16)
* test: add EditorFooter tests
2022-02-22 13:24:15 -05:00
Ben Warzeski
d2e89d7b28 chore: rename lms service to cms (#15)
* chore: rename lms service to cms

* fix: remove typo

* fix: remove old selector
2022-02-22 12:59:37 -05:00
Ben Warzeski
362139edd2 feat: mock paragon and i18n library for tests 2022-02-22 12:45:30 -05:00
Ben Warzeski
5a1d71a62c !refactor: Breaking Change refactor use Redux. No release 2022-02-18 13:16:36 -05:00
connorhaugh
eef30348fd feat: add plugins including image-upload (#12)
This adds the image upload "plugin" and all the desired built-in plugins.
Per the following two tickets
https://openedx.atlassian.net/browse/TNL-9367
https://openedx.atlassian.net/browse/TNL-9475

I need to add the requisite plugins, as well as a framework for the image upload modal.
2022-02-14 12:33:49 -05:00
connorhaugh
2f931b5bdb fix: dont encode with uri twice (#10) 2022-01-27 12:39:19 -05:00
connorhaugh
d8c6b8dddd feat: Text Editor and V2 Editor Framework (#9)
Text Editor and V2 Editor Framework. Documentation to come.
2022-01-25 14:04:57 -05:00
kenclary
c93c5e986a Merge pull request #8 from edx/kenclary/release-fix
fix: correct project links in package.json
2021-12-15 11:34:36 -05:00
Ken Clary
bb7360ac93 fix: correct project links in package.json 2021-12-15 11:31:46 -05:00
kenclary
f7935deea0 Merge pull request #7 from edx/kenclary/release-fix
fix: correct(?) configuration of main branch for semantic-release.
2021-12-15 11:01:48 -05:00
Ken Clary
b98fe329af fix: correct(?) configuration of main branch for semantic-release. 2021-12-15 10:52:22 -05:00
kenclary
2bd75952f0 Merge pull request #6 from edx/kenclary/security
fix: update dependencies for security.
2021-12-14 17:22:23 -05:00
Ken Clary
f44017e5f4 fix: update dependencies for security. 2021-12-14 17:12:22 -05:00
kenclary
621f39f8ca Merge pull request #4 from edx/kenclary/release
fix: base semantic-release on main branch.
2021-12-13 11:30:33 -05:00
Ken Clary
159ecc84c3 fix: base semantic-release on main branch. 2021-12-09 16:06:16 -05:00
kenclary
e5a1694c90 Merge pull request #3 from edx/kclary/node
fix: update node to 16, using .nvmrc file, to support later versions of semantic-release.
2021-12-03 16:48:58 -05:00
Ken Clary
b37db23e8f fix: update node to 16, using .nvmrc file, to support later versions of semantic-release. 2021-12-03 12:10:06 -05:00
kenclary
105c29a67a Merge pull request #2 from edx/kenclary-initial
feat: setup repo as NPM package with edX standards.
2021-12-01 20:09:26 -05:00
Ken Clary
a48eb0aaf4 feat: setup repo as NPM package with edX standards. 2021-12-01 12:41:54 -05:00
kenclary
7142f89211 Merge pull request #1 from edx/kenclary-adr
Create 0001-library-adr.rst
2021-11-23 09:02:46 -05:00
kenclary
f547e5ed1f Create 0001-library-adr.rst
Draft of ADR for repo.
2021-11-22 16:52:19 -05:00
David Joy
9ed78de9e2 Initial commit 2021-11-19 14:28:50 -05:00
2303 changed files with 242013 additions and 43531 deletions

26
.env
View File

@@ -1,3 +1,4 @@
APP_ID='authoring'
NODE_ENV='production'
ACCESS_TOKEN_COOKIE_NAME=''
BASE_URL=''
@@ -16,14 +17,37 @@ LOGO_URL=''
LOGO_WHITE_URL=''
LOGOUT_URL=null
MARKETING_SITE_BASE_URL=''
TERMS_OF_SERVICE_URL=''
PRIVACY_POLICY_URL=''
ORDER_HISTORY_URL=''
PUBLISHER_BASE_URL=''
REFRESH_ACCESS_TOKEN_ENDPOINT=''
SEGMENT_KEY=''
SITE_NAME=''
STUDIO_SHORT_NAME='Studio'
SUPPORT_EMAIL=''
SUPPORT_URL=''
USER_INFO_COOKIE_NAME=''
ENABLE_ACCESSIBILITY_PAGE=false
ENABLE_PROGRESS_GRAPH_SETTINGS=false
ENABLE_TEAM_TYPE_SETTING=false
ENABLE_NEW_EDITOR_PAGES=true
ENABLE_UNIT_PAGE=false
ENABLE_ASSETS_PAGE=false
ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN=false
ENABLE_TAGGING_TAXONOMY_PAGES=true
ENABLE_CERTIFICATE_PAGE=true
ENABLE_COURSE_IMPORT_IN_LIBRARY=false
ENABLE_UNIT_PAGE_NEW_DESIGN=false
ENABLE_COURSE_OUTLINE_NEW_DESIGN=false
BBB_LEARN_MORE_URL=''
HOTJAR_APP_ID=''
HOTJAR_VERSION=6
HOTJAR_DEBUG=false
INVITE_STUDENTS_EMAIL_TO=''
ENABLE_CHECKLIST_QUALITY=''
# "Multi-level" blocks are unsupported in libraries
LIBRARY_UNSUPPORTED_BLOCKS="conditional,step-builder,problem-builder,library_content,itembank"
# Fallback in local style files
PARAGON_THEME_URLS={}
COURSE_TEAM_SUPPORT_EMAIL=''
ADMIN_CONSOLE_URL='http://localhost:2025/admin-console'

View File

@@ -1,6 +1,7 @@
APP_ID='authoring'
NODE_ENV='development'
ACCESS_TOKEN_COOKIE_NAME='edx-jwt-cookie-header-payload'
BASE_URL='localhost:2001'
BASE_URL='http://localhost:2001'
CREDENTIALS_BASE_URL='http://localhost:18150'
CSRF_TOKEN_API_PATH='/csrf/api/v1/token'
DISCOVERY_API_BASE_URL=
@@ -16,16 +17,40 @@ LOGO_URL=https://edx-cdn.org/v3/default/logo.svg
LOGO_WHITE_URL=https://edx-cdn.org/v3/default/logo-white.svg
LOGOUT_URL='http://localhost:18000/logout'
MARKETING_SITE_BASE_URL='http://localhost:18000'
TERMS_OF_SERVICE_URL=
PRIVACY_POLICY_URL=
ORDER_HISTORY_URL='localhost:1996/orders'
PORT=2001
PUBLISHER_BASE_URL=
REFRESH_ACCESS_TOKEN_ENDPOINT='http://localhost:18000/login_refresh'
SEGMENT_KEY=null
SITE_NAME='edX'
SITE_NAME='Your Plaform Name Here'
STUDIO_BASE_URL='http://localhost:18010'
SUPPORT_EMAIL='support@example.com'
STUDIO_SHORT_NAME='Studio'
SUPPORT_EMAIL=
SUPPORT_URL='https://support.edx.org'
USER_INFO_COOKIE_NAME='edx-user-info'
ENABLE_ACCESSIBILITY_PAGE=false
ENABLE_PROGRESS_GRAPH_SETTINGS=false
ENABLE_TEAM_TYPE_SETTING=false
ENABLE_NEW_EDITOR_PAGES=true
ENABLE_UNIT_PAGE=false
ENABLE_ASSETS_PAGE=false
ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN=true
ENABLE_CERTIFICATE_PAGE=true
ENABLE_COURSE_IMPORT_IN_LIBRARY=true
ENABLE_COURSE_OUTLINE_NEW_DESIGN=true
ENABLE_UNIT_PAGE_NEW_DESIGN=true
ENABLE_NEW_VIDEO_UPLOAD_PAGE=true
ENABLE_TAGGING_TAXONOMY_PAGES=true
BBB_LEARN_MORE_URL=''
HOTJAR_APP_ID=''
HOTJAR_VERSION=6
HOTJAR_DEBUG=true
INVITE_STUDENTS_EMAIL_TO="someone@domain.com"
ENABLE_CHECKLIST_QUALITY=true
# "Multi-level" blocks are unsupported in libraries
LIBRARY_UNSUPPORTED_BLOCKS="conditional,step-builder,problem-builder,library_content,itembank"
# Fallback in local style files
PARAGON_THEME_URLS={}
COURSE_TEAM_SUPPORT_EMAIL=''
ADMIN_CONSOLE_URL='http://localhost:2025/admin-console'

View File

@@ -1,5 +1,6 @@
APP_ID='authoring'
ACCESS_TOKEN_COOKIE_NAME='edx-jwt-cookie-header-payload'
BASE_URL='localhost:2001'
BASE_URL='http://localhost:2001'
CREDENTIALS_BASE_URL='http://localhost:18150'
CSRF_TOKEN_API_PATH='/csrf/api/v1/token'
DISCOVERY_API_BASE_URL='http://localhost:18381'
@@ -22,9 +23,24 @@ REFRESH_ACCESS_TOKEN_ENDPOINT='http://localhost:18000/login_refresh'
SEGMENT_KEY=null
SITE_NAME='edX'
STUDIO_BASE_URL='http://localhost:18010'
STUDIO_SHORT_NAME='Studio'
SUPPORT_EMAIL='support@example.com'
SUPPORT_URL='https://support.edx.org'
USER_INFO_COOKIE_NAME='edx-user-info'
ENABLE_PROGRESS_GRAPH_SETTINGS=false
ENABLE_TEAM_TYPE_SETTING=false
ENABLE_NEW_EDITOR_PAGES=true
ENABLE_UNIT_PAGE=true
ENABLE_ASSETS_PAGE=false
ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN=true
ENABLE_CERTIFICATE_PAGE=true
ENABLE_COURSE_IMPORT_IN_LIBRARY=true
ENABLE_COURSE_OUTLINE_NEW_DESIGN=false
ENABLE_UNIT_PAGE_NEW_DESIGN=false
ENABLE_TAGGING_TAXONOMY_PAGES=true
BBB_LEARN_MORE_URL=''
INVITE_STUDENTS_EMAIL_TO="someone@domain.com"
ENABLE_CHECKLIST_QUALITY=true
# "Multi-level" blocks are unsupported in libraries
LIBRARY_UNSUPPORTED_BLOCKS="conditional,step-builder,problem-builder,library_content,itembank"
PARAGON_THEME_URLS=
COURSE_TEAM_SUPPORT_EMAIL='support@example.com'

View File

@@ -1,4 +1,6 @@
coverage/*
dist/
node_modules/
jest.config.js
jest.config.js
env.config.jsx
example.env.config.jsx

View File

@@ -1,6 +1,9 @@
const { createConfig } = require('@edx/frontend-build');
const path = require('path');
// eslint-disable-next-line import/no-extraneous-dependencies
const { createConfig } = require('@openedx/frontend-build');
module.exports = createConfig('eslint',
module.exports = createConfig(
'eslint',
{
rules: {
'jsx-a11y/label-has-associated-control': [2, {
@@ -8,6 +11,34 @@ module.exports = createConfig('eslint',
}],
'template-curly-spacing': 'off',
'react-hooks/exhaustive-deps': 'off',
indent: 'off',
'no-restricted-exports': 'off',
// There is no reason to disallow this syntax anymore; we don't use regenerator-runtime in new browsers
'no-restricted-syntax': 'off',
'no-restricted-imports': ['error', {
patterns: [
{
group: ['@edx/frontend-platform/i18n'],
importNames: ['injectIntl'],
message: "Use 'useIntl' hook instead of injectIntl.",
},
],
}],
},
});
settings: {
// Import URLs should be resolved using aliases
'import/resolver': {
webpack: {
config: path.resolve(__dirname, 'webpack.dev.config.js'),
},
},
},
overrides: [
{
files: ['plugins/**/*.test.jsx'],
rules: {
'import/no-extraneous-dependencies': 'off',
},
},
],
},
);

7
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,7 @@
version: 2
updates:
# Adding new check for github-actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

38
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,38 @@
## Description
Describe what this pull request changes, and why. Include implications for people using this change.
Design decisions and their rationales should be documented in the repo (docstring / ADR), per
[OEP-19](https://open-edx-proposals.readthedocs.io/en/latest/oep-0019-bp-developer-documentation.html), and can be linked here.
Useful information to include:
- Which user roles will this change impact? Common user roles are "Learner", "Course Author",
"Developer", and "Operator".
- Include screenshots for changes to the UI (ideally, both "before" and "after" screenshots, if applicable).
## Supporting information
Link to other information about the change, such as GitHub issues, or Discourse discussions.
Be sure to check they are publicly readable, or if not, repeat the information here.
## Testing instructions
Please provide detailed step-by-step instructions for manually testing this change.
## Other information
Include anything else that will help reviewers and consumers understand the change.
- Does this change depend on other changes elsewhere?
- Any special concerns or limitations? For example: deprecations, migrations, security, or accessibility.
## Best Practices Checklist
We're trying to move away from some deprecated patterns in this codebase. Please
check if your PR meets these recommendations before asking for a review:
- [ ] Any _new_ files are using TypeScript (`.ts`, `.tsx`).
- [ ] Avoid `propTypes` and `defaultProps` in any new or modified code.
- [ ] Tests should use the helpers in `src/testUtils.tsx` (specifically `initializeMocks`)
- [ ] Do not add new fields to the Redux state/store. Use React Context to share state among multiple components.
- [ ] Use React Query to load data from REST APIs. See any `apiHooks.ts` in this repo for examples.
- [ ] All new i18n messages in `messages.ts` files have a `description` for translators to use.
- [ ] Avoid using `../` in import paths. To import from parent folders, use `@src`, e.g. `import { initializeMocks } from '@src/testUtils';` instead of `from '../../../../testUtils'`

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,18 @@
# Run the workflow that adds new tickets that are labelled "release testing"
# to the org-wide BTR project board
name: Add release testing issues to the BTR project board
on:
issues:
types: [labeled]
# This workflow is triggered when an issue is labeled with 'release testing'.
# It adds the issue to the BTR project and applies the 'needs triage' label
# if it doesn't already have it.
jobs:
handle-release-testing:
uses: openedx/.github/.github/workflows/add-issue-to-btr-project.yml@master
secrets:
GITHUB_APP_ID: ${{ secrets.GRAPHQL_AUTH_APP_ID }}
GITHUB_APP_PRIVATE_KEY: ${{ secrets.GRAPHQL_AUTH_APP_PEM }}

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

15
.github/workflows/add-to-cc-board.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
name: Trigger to add Issue or PR to a Core Contributor project board
on:
issues:
types: [labeled]
pull_request:
types: [labeled]
jobs:
add-to-cc-board:
if: github.event.label.name == 'Core Contributor assignee'
uses: openedx/.github/.github/workflows/add-to-cc-board.yml@master
with:
board_name: cc-frontend-apps
secrets:
projects_access_token: ${{ secrets.PROJECTS_TOKEN }}

View File

@@ -10,4 +10,4 @@ on:
jobs:
version-check:
uses: openedx/.github/.github/workflows/lockfileversion-check.yml@master
uses: openedx/.github/.github/workflows/lockfileversion-check-v3.yml@master

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

View File

@@ -0,0 +1,12 @@
name: Update Browserslist DB
on:
schedule:
- cron: '0 0 * * 1'
workflow_dispatch:
jobs:
update-browserslist:
uses: openedx/.github/.github/workflows/update-browserslist-db.yml@master
secrets:
requirements_bot_github_token: ${{ secrets.requirements_bot_github_token }}

View File

@@ -9,16 +9,31 @@ on:
jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
node: [16]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node }}
node-version-file: '.nvmrc'
- run: make validate.ci
- name: Archive code coverage results
uses: actions/upload-artifact@v6
with:
name: code-coverage-report
path: coverage/*.*
coverage:
runs-on: ubuntu-latest
needs: tests
steps:
- uses: actions/checkout@v6
- name: Download code coverage results
uses: actions/download-artifact@v7
with:
pattern: code-coverage-report
path: coverage
merge-multiple: true
- name: Upload coverage
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v5
with:
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}

10
.gitignore vendored
View File

@@ -1,6 +1,7 @@
.DS_Store
.eslintcache
.idea
.run
node_modules
npm-debug.log
coverage
@@ -20,3 +21,12 @@ temp/babel-plugin-react-intl
/temp
/.vscode
/module.config.js
# Local environment overrides
.env.private
# Messages .json files fetched by atlas
src/i18n/messages/
# environment js config
env.config.jsx

2
.nvmrc
View File

@@ -1 +1 @@
v16
24

23
.oxlintrc.json Normal file
View File

@@ -0,0 +1,23 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"categories": {
"correctness": "warn"
},
"rules": {
"eslint/no-unused-vars": "off",
"typescript/unbound-method": "off", // 🛑 TEMPORARY
"typescript/no-floating-promises": ["error", {
"allowForKnownSafeCalls": [
// queryClient.invalidateQueries returns a promise that can be awaited
// if you want to do something after all the subsequent refetches are
// complete, but we rarely if ever want that; we usually want to
// continue invalidating more things immediately. So we don't usually
// want to await this.
"invalidateQueries",
]
}]
},
"ignorePatterns": [
"webpack.dev-tutor.config.js",
]
}

35
.stylelintrc.json Normal file
View File

@@ -0,0 +1,35 @@
{
"extends": ["@edx/stylelint-config-edx"],
"rules": {
"selector-pseudo-class-no-unknown": [true, {
"ignorePseudoClasses": ["export"]
}],
"unit-no-unknown": [true, {
"ignoreUnits": ["\\.5"]
}],
"property-no-vendor-prefix": [true, {
"ignoreProperties": ["animation", "filter", "transform", "transition"]
}],
"value-no-vendor-prefix": [true, {
"ignoreValues": ["fill-available"]
}],
"function-no-unknown": null,
"number-leading-zero": "never",
"no-descending-specificity": null,
"selector-class-pattern": null,
"scss/no-global-function-names": null,
"color-hex-case": "upper",
"color-hex-length": "long",
"scss/dollar-variable-empty-line-before": null,
"scss/dollar-variable-colon-space-after": "at-least-one-space",
"at-rule-no-unknown": null,
"scss/at-rule-no-unknown": true,
"scss/at-import-partial-extension": null,
"scss/comment-no-empty": null,
"import-notation": "string",
"property-no-unknown": [true, {
"ignoreProperties": ["xs", "sm", "md", "lg", "xl", "xxl"]
}],
"alpha-value-notation": "number"
}
}

View File

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

42
Makefile Executable file → Normal file
View File

@@ -1,22 +1,17 @@
transifex_resource = frontend-app-course-authoring
export TRANSIFEX_RESOURCE = ${transifex_resource}
transifex_langs = "ar,fr,es_419,zh_CN"
intl_imports = ./node_modules/.bin/intl-imports.js
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
transifex_temp = ./temp/babel-plugin-formatjs
precommit:
npm run lint
npm audit
requirements:
npm install
npm ci
i18n.extract:
# Pulling display strings from .jsx files into .json files...
@@ -34,20 +29,18 @@ detect_changed_source_translations:
# Checking for changed translations...
git diff --exit-code $(i18n)
# Pushes translations to Transifex. You must run make extract_translations first.
push_translations:
# Pushing strings to Transifex...
tx push -s
# Fetching hashes from Transifex...
./node_modules/@edx/reactifex/bash_scripts/get_hashed_strings_v3.sh
# Writing out comments to file...
$(transifex_utils) $(transifex_temp) --comments --v3-scripts-path
# Pushing comments to Transifex...
./node_modules/@edx/reactifex/bash_scripts/put_comments_v3.sh
# Pulls translations from Transifex.
pull_translations:
tx pull -f --mode reviewed --languages=$(transifex_langs)
rm -rf src/i18n/messages
mkdir src/i18n/messages
cd src/i18n/messages \
&& atlas pull $(ATLAS_OPTIONS) \
translations/frontend-component-ai-translations/src/i18n/messages:frontend-component-ai-translations \
translations/frontend-platform/src/i18n/messages:frontend-platform \
translations/paragon/src/i18n/messages:paragon \
translations/frontend-component-footer/src/i18n/messages:frontend-component-footer \
translations/frontend-app-course-authoring/src/i18n/messages:frontend-app-course-authoring
$(intl_imports) frontend-component-ai-translations frontend-platform paragon frontend-component-footer frontend-app-course-authoring
# This target is used by Travis.
validate-no-uncommitted-package-lock-changes:
@@ -58,8 +51,11 @@ validate-no-uncommitted-package-lock-changes:
validate:
make validate-no-uncommitted-package-lock-changes
npm run i18n_extract
npm run lint -- --max-warnings 0
npm run test
# We are trying out oxlint. Now that it's been working well for a while with both oxlint and eslint, we have disabled
# eslint, and after a few weeks we'll evaluate whether any problems are slipping through if only oxlint is used.
npm run oxlint
npm run types
npm run test:ci
npm run build
.PHONY: validate.ci

View File

@@ -1,39 +1,284 @@
|Build Status| |Codecov| |license|
frontend-app-authoring
######################
frontend-app-course-authoring
=============================
|license-badge| |status-badge| |codecov-badge|
Please tag `@edx/teaching-and-learning <https://github.com/orgs/edx/teams/teaching-and-learning>`_ on any PRs or issues. Thanks.
Prerequisite
Purpose
*******
This implements most of the frontend for **Open edX Studio**, allowing authors to create and edit courses, libraries, and their learning components.
A few parts of Studio still default to the `"legacy" pages defined in edx-platform <https://github.com/openedx/edx-platform/tree/master/cms>`_, but those are rapidly being deprecated and replaced with the React- and Paragon-based pages defined here.
Getting Started
************
Prerequisites
=============
`Tutor`_ is currently recommended as a development environment for the Authoring
MFE. Most likely, it already has this MFE configured; however, you'll need to
make some changes in order to run it in development mode. You can refer
to the `relevant tutor-mfe documentation`_ for details, or follow the quick
guide below.
.. _Tutor: https://github.com/overhangio/tutor
.. _relevant tutor-mfe documentation: https://github.com/overhangio/tutor-mfe#mfe-development
Cloning and Setup
=================
1. Clone your new repo:
.. code-block:: bash
git clone https://github.com/openedx/frontend-app-authoring.git
2. Use the version of Node specified in the ``.nvmrc`` file.
The current version of the micro-frontend build scripts supports the version of Node found in ``.nvmrc``.
Using other major versions of node *may* work, but this is unsupported. For
convenience, this repository includes an ``.nvmrc`` file to help in setting the
correct node version via `nvm <https://github.com/nvm-sh/nvm>`_.
3. Stop the Tutor devstack, if it's running: ``tutor dev stop``
4. Next, we need to tell Tutor that we're going to be running this repo in
development mode, and it should be excluded from the ``mfe`` container that
otherwise runs every MFE. Run this:
.. code-block:: bash
tutor mounts add /path/to/frontend-app-authoring
5. Start Tutor in development mode. This command will start the LMS and Studio,
and other required MFEs like ``authn`` and ``account``, but will not start
the Authoring MFE, which we're going to run on the host instead of in a
container managed by Tutor. Run:
.. code-block:: bash
tutor dev start lms cms mfe
Startup
=======
1. Install npm dependencies:
.. code-block:: bash
cd frontend-app-authoring && npm ci
2. Start the dev server:
.. code-block:: bash
npm run dev
Then you can access the app at http://apps.local.openedx.io:2001/course-authoring/home
Troubleshooting
---------------
* If you see an "Invalid Host header" error, then you're probably using a different domain name for your devstack such as
``local.edly.io`` or ``local.overhang.io`` (not the new recommended default, ``local.openedx.io``). In that case, run
these commands to update your devstack's domain names:
.. code-block:: bash
tutor dev stop
tutor config save --set LMS_HOST=local.openedx.io --set CMS_HOST=studio.local.openedx.io
tutor dev launch -I --skip-build
tutor dev stop authoring # We will run this MFE on the host
* If tutor-mfe is not starting the authoring MFE in development mode (eg. `tutor dev start authoring` fails), it may be due to
using a tutor version that expects the MFE name to be frontend-app-course-authoring (the previous name of this repo). To fix
this, you can rename the cloned repo directory to frontend-app-course-authoring. More information can be found in
`this forum post <https://discuss.openedx.org/t/repo-rename-frontend-app-course-authoring-frontend-app-authoring/13930/2>`__.
Features
********
Feature: Pages and Resources Studio Tab
=======================================
Enables a "Pages & Resources" menu item in Studio, under the "Content" menu.
.. image:: ./docs/readme-images/feature-pages-resources.png
Requirements
------------
`Devstack <https://edx.readthedocs.io/projects/edx-installing-configuring-and-running/en/latest/installation/index.html>`_. If you start Devstack with ``make dev.up.studio`` that should give you everything you need as a companion to this frontend.
The following are requirements for this feature to function correctly:
Installation and Startup
------------------------
* ``edx-platform`` Waffle flags:
1. Clone the repo:
* ``discussions.pages_and_resources_mfe``: must be enabled for the set of users meant to access this feature.
``git clone https://github.com/openedx/frontend-app-course-authoring.git``
* `frontend-app-learning <https://github.com/openedx/frontend-app-learning>`_: This MFE expects it to be the LMS frontend.
* `frontend-app-discussions <https://github.com/openedx/frontend-app-discussions/>`_: This is what the "Discussions" configuration provided by this feature actually configures. Without it, discussion settings are ignored.
2. Install npm dependencies:
Configuration
-------------
``cd frontend-app-course-authoring && npm install``
In additional to the standard settings, the following local configuration items are required:
3. Start the dev server:
* ``LEARNING_BASE_URL``: points to Learning MFE; necessary so that the `View Live` button works
* ``ENABLE_PROGRESS_GRAPH_SETTINGS``: allow enabling or disabling the learner progress graph course-wide
``npm start``
Feature Description
-------------------
Clicking on the "Pages & Resources" menu item takes the user to the course's ``pages-and-resources`` standalone page in this MFE. (In a devstack, for instance: http://localhost:2001/course/course-v1:edX+DemoX+Demo_Course/pages-and-resources.)
UX-wise, **Pages & Resources** is meant to look like a Studio tab, so reproduces Studio's header.
For a particular course, this page allows one to:
* Configure the new Discussions MFE (making this a requirement for it). This includes:
* Enabling/disabling the feature entirely
* Picking a different discussion provider, while showing a comparison matrix between them:
* edX
* Ed Discussion
* InScribe
* Piazza
* Yellowdig
* Allowing to configure the selected provider
* Enable/Disable learner progress
* Enable/Disable learner notes
* Enable/Disable the learner wiki
* Enable/Disable the LMS calculator
* Go to the textbook management page in Studio (in a devstack: http://localhost:18010/textbooks/course-v1:edX+DemoX+Demo_Course)
* Go to the custom page management page in Studio(in a devstack http://localhost:18010/tabs/course-v1:edX+DemoX+Demo_Course)
Feature: New React XBlock Editors
=================================
.. image:: ./docs/readme-images/feature-problem-editor.png
New React editors for the HTML, Video, and Problem XBlocks are provided here and are rendered by this MFE instead of by the XBlock's authoring view.
Feature: New Proctoring Exams View
==================================
.. image:: ./docs/readme-images/feature-proctored-exams.png
Requirements
------------
* `edx-exams <https://github.com/edx/edx-exams>`_: for this feature to work, the ``edx-exams`` IDA must be deployed and its API accessible by the browser
Configuration
-------------
In additional to the standard settings, the following local configuration item is required:
* ``EXAMS_BASE_URL``: URL to the ``edx-exams`` deployment
Feature Description
-------------------
In Studio, a new item ("Proctored Exam Settings") is added to "Other Course Settings" in the course's "Certificates" settings page. When clicked, this takes the author to the corresponding page in the Course Authoring MFE, where one can:
* Enable proctored exams for the course
* Allow opting out of proctored exams
* Select a proctoring provider
Feature: Advanced Settings
==========================
.. image:: ./docs/readme-images/feature-advanced-settings.png
In Studio, the "Advanced Settings" page for each enabled course will now be served by this frontend, instead of the UI built into edx-platform. The advanced settings page holds many different settings for the course, such as what features or XBlocks are enabled.
Feature: Files & Uploads
==========================
.. image:: ./docs/readme-images/feature-files-uploads.png
In Studio, the "Files & Uploads" page for each enabled course will now be served by this frontend, instead of the UI built into edx-platform. This page allows managing static asset files like PDFs, images, etc. used for the course.
Feature: Course Updates
==========================
.. image:: ./docs/readme-images/feature-course-updates.png
Feature: Import/Export Pages
============================
.. image:: ./docs/readme-images/feature-export.png
Feature: Tagging/Taxonomy Pages
================================
.. image:: ./docs/readme-images/feature-tagging-taxonomy-pages.png
Requirements
------------
* ``edx-platform`` Waffle flags:
* ``new_studio_mfe.use_tagging_taxonomy_list_page``: this feature flag must be enabled.
Configuration
-------------
In additional to the standard settings, the following local configuration items are required:
* ``ENABLE_TAGGING_TAXONOMY_PAGES``: must be enabled (which it is by default) in order to actually enable/show the new
Tagging/Taxonomy functionality.
Feature: Libraries V2/Legacy Tabs
=================================
Configuration
-------------
In additional to the standard settings, the following local configurations can be set to switch between different library modes:
* ``MEILISEARCH_ENABLED``: Studio setting which is enabled when the `meilisearch plugin`_ is installed.
* ``edx-platform`` Waffle flags:
* ``contentstore.new_studio_mfe.disable_legacy_libraries``: this feature flag must be OFF to show legacy Libraries V1
* ``contentstore.new_studio_mfe.disable_new_libraries``: this feature flag must be OFF to show Content Libraries V2
.. _meilisearch plugin: https://github.com/open-craft/tutor-contrib-meilisearch
Developing
**********
`Tutor <https://docs.tutor.edly.io/>`_ is the community-supported Open edX development environment. See the `tutor-mfe plugin README <https://github.com/overhangio/tutor-mfe?tab=readme-ov-file#mfe-development>`_ for more information.
The dev server is running at `http://localhost:2001 <http://localhost:2001>`_.
If your devstack includes the default Demo course, you can visit the following URLs to see content:
- `Proctored Exam Settings <http://localhost:2001/course/course-v1:edX+DemoX+Demo_Course/proctored-exam-settings>`_
- `Pages and Resources <http://localhost:2001/course/course-v1:edX+DemoX+Demo_Course/pages-and-resources>`_ (work in progress)
- `Pages and Resources <http://localhost:2001/course/course-v1:edX+DemoX+Demo_Course/pages-and-resources>`_
Troubleshooting
========================
* ``npm ERR! gyp ERR! build error`` while running npm install on Macs with M1 processors: Probably due to a compatibility issue of node-canvas with M1.
Run ``brew install pkg-config pixman cairo pango libpng jpeg giflib librsvg`` before ``npm install`` to get the correct versions of the dependencies.
If there is still an error, look for "no package [...] found" in the error message and install missing package via brew.
(https://github.com/Automattic/node-canvas/issues/1733)
Deploying
*********
Production Build
----------------
================
The production build is created with ``npm run build``.
@@ -41,5 +286,108 @@ The production build is created with ``npm run build``.
:target: https://travis-ci.com/edx/frontend-app-course-authoring
.. |Codecov| image:: https://codecov.io/gh/edx/frontend-app-course-authoring/branch/master/graph/badge.svg
:target: https://codecov.io/gh/edx/frontend-app-course-authoring
.. |license| image:: https://img.shields.io/npm/l/@edx/frontend-app-course-authoring.svg
:target: @edx/frontend-app-course-authoring
.. |license| image:: https://img.shields.io/npm/l/@edx/frontend-app-authoring.svg
:target: @edx/frontend-app-authoring
Internationalization
====================
Please see refer to the `frontend-platform i18n howto`_ for documentation on
internationalization.
.. _frontend-platform i18n howto: https://github.com/openedx/frontend-platform/blob/master/docs/how_tos/i18n.rst
Getting Help
************
If you're having trouble, we have discussion forums at
https://discuss.openedx.org where you can connect with others in the community.
Our real-time conversations are on Slack. You can request a `Slack
invitation`_, then join our `community Slack workspace`_. Because this is a
frontend repository, the best place to discuss it would be in the `#wg-frontend
channel`_.
For anything non-trivial, the best path is to open an issue in this repository
with as many details about the issue you are facing as you can provide.
https://github.com/openedx/frontend-app-course-authoring/issues
For more information about these options, see the `Getting Help`_ page.
.. _Slack invitation: https://openedx.org/slack
.. _community Slack workspace: https://openedx.slack.com/
.. _#wg-frontend channel: https://openedx.slack.com/archives/C04BM6YC7A6
.. _Getting Help: https://openedx.org/community/connect
Legacy Studio
*************
If you would like to use legacy studio for certain features, you can set the following waffle flags in ``edx-platform``:
* ``legacy_studio.text_editor``: loads the legacy HTML Xblock editor when editing a text block
* ``legacy_studio.video_editor``: loads the legacy Video editor when editing a video block
* ``legacy_studio.problem_editor``: loads the legacy Problem editor when editing a problem block
* ``legacy_studio.advanced_settings``: Advanced Settings page
* ``legacy_studio.updates``: Updates page
* ``legacy_studio.export``: Export page
* ``legacy_studio.import``: Import page
* ``legacy_studio.files_uploads``: Files page
* ``legacy_studio.exam_settings``: loads the legacy Exam Settings
License
*******
The code in this repository is licensed under the AGPLv3 unless otherwise
noted.
Please see `LICENSE <LICENSE>`_ for details.
Contributing
************
Contributions are very welcome. Please read `How To Contribute`_ for details.
.. _How To Contribute: https://openedx.org/r/how-to-contribute
This project is currently accepting all types of contributions, bug fixes,
security fixes, maintenance work, or new features. However, please make sure
to have a discussion about your new feature idea with the maintainers prior to
beginning development to maximize the chances of your change being accepted.
You can start a conversation by creating a new issue on this repo summarizing
your idea.
The Open edX Code of Conduct
****************************
All community members are expected to follow the `Open edX Code of Conduct`_.
.. _Open edX Code of Conduct: https://openedx.org/code-of-conduct/
People
******
The assigned maintainers for this component and other project details may be
found in `Backstage`_. Backstage pulls this data from the ``catalog-info.yaml``
file in this repo.
.. _Backstage: https://open-edx-backstage.herokuapp.com/catalog/default/component/frontend-app-course-authoring
Reporting Security Issues
*************************
Please do not report security issues in public, and email security@openedx.org instead.
.. |license-badge| image:: https://img.shields.io/github/license/openedx/frontend-app-course-authoring.svg
:target: https://github.com/openedx/frontend-app-course-authoring/blob/master/LICENSE
:alt: License
.. |status-badge| image:: https://img.shields.io/badge/Status-Maintained-brightgreen
.. |codecov-badge| image:: https://codecov.io/github/openedx/frontend-app-course-authoring/coverage.svg?branch=master
:target: https://codecov.io/github/openedx/frontend-app-course-authoring?branch=master
:alt: Codecov

19
catalog-info.yaml Normal file
View File

@@ -0,0 +1,19 @@
# This file records information about this repo. Its use is described in OEP-55:
# https://open-edx-proposals.readthedocs.io/en/latest/processes/oep-0055-proc-project-maintainers.html
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: 'frontend-app-authoring'
description: "The frontend (MFE) for Open edX Authoring (aka Studio)"
links:
- url: "https://github.com/openedx/frontend-app-authoring"
title: "Frontend app authoring"
icon: "Web"
annotations:
openedx.org/arch-interest-groups: ""
openedx.org/release: "master"
spec:
owner: user:bradenmacdonald
type: 'website'
lifecycle: 'production'

View File

@@ -8,3 +8,8 @@ coverage:
default:
target: auto
threshold: 0%
ignore:
- "src/grading-settings/grading-scale/react-ranger.js"
- "src/generic/DraggableList/verticalSortableList.ts"
- "src/container-comparison/data/api.mock.ts"
- "src/index.js"

View File

@@ -0,0 +1,80 @@
Override External URLs
======================
What is getExternalLinkUrl?
---------------------------
The `getExternalLinkUrl` function is a utility from `@edx/frontend-platform` that allows for centralized management of external URLs. It enables the override of external links through configuration, making it possible to customize external references without modifying the source code directly.
URLs wrapped with getExternalLinkUrl
------------------------------------
Use cases:
1. **Accessibility Page** (`src/accessibility-page/AccessibilityPage.jsx`)
- `COMMUNITY_ACCESSIBILITY_LINK` - Points to community accessibility resources: https://www.edx.org/accessibility
2. **Course Outline** (if applicable)
- Documentation links
- Help resources
3. **Other pages** (search for `getExternalLinkUrl` usage across the codebase)
- Help documentation
- External tool integrations
Following external URLs are wrapped with `getExternalLinkUrl` in the authoring application:
- 'https://www.edx.org/accessibility'
- 'https://docs.openedx.org/en/latest/educators/concepts/exercise_tools/about_multi_select.html'
- 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/exercise_tools/add_multi_select.html'
- 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/exercise_tools/add_dropdown.html'
- 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/exercise_tools/manage_numerical_input_problem.html'
- 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/exercise_tools/add_text_input.html'
- 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/social_sharing.html'
- 'https://docs.openedx.org/en/latest/educators/references/course_development/exercise_tools/guide_problem_types.html#advanced-problem-types'
- 'https://docs.openedx.org/en/latest/educators/references/course_development/parent_child_components.html'
- 'https://openai.com/api-data-privacy'
- 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/create_new_library.html'
- 'https://bigbluebutton.org/privacy-policy/'
- 'https://creativecommons.org/about'
Note: as new external URLs are added to the codebase, more URLs will be wrapped with `getExternalLinkUrl` and this list may not always be up to date.
How to Override External URLs
-----------------------------
To override external URLs, you can use the frontend platform's configuration system.
This object should be added to the config object defined in the env.config.[js,jsx,ts,tsx], and must be named externalLinkUrlOverrides.
1. **Environment Configuration**
Add the URL overrides to your environment configuration:
.. code-block:: javascript
const config = {
// Other config options...
externalLinkUrlOverrides: {
'https://www.edx.org/accessibility': 'https://your-custom-domain.com/accessibility',
// Add other URL overrides here
}
};
Examples
--------
**Original URL:** Default community accessibility link
**Override:** Your institution's accessibility policy page
.. code-block:: javascript
// In your app configuration
getExternalLinkUrl('https://www.edx.org/accessibility')
// Returns: 'https://your-custom-domain.com/accessibility'
// Instead of the default Open edX community link
Benefits
--------
- **Customization**: Institutions can point to their own resources
- **Maintainability**: URLs can be changed without code modifications
- **Consistency**: Centralized URL management across the application
- **Flexibility**: Different environments can have different external links

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

24
example.env.config.jsx Normal file
View File

@@ -0,0 +1,24 @@
import WholeCourseTranslation from '@edx/course-app-translation-plugin';
import { PLUGIN_OPERATIONS, DIRECT_PLUGIN } from '@openedx/frontend-plugin-framework';
// Load environment variables from .env file
const config = {
...process.env,
pluginSlots: {
additional_course_plugin: {
plugins: [
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'whole-course-translation-plugin',
type: DIRECT_PLUGIN,
priority: 1,
RenderWidget: WholeCourseTranslation,
},
},
],
},
},
};
export default config;

View File

@@ -1,17 +1,21 @@
const { createConfig } = require('@edx/frontend-build');
const { createConfig } = require('@openedx/frontend-build');
module.exports = createConfig('jest', {
setupFilesAfterEnv: [
'jest-expect-message',
'<rootDir>/src/setupTest.js',
],
coveragePathIgnorePatterns: [
'src/setupTest.js',
'src/i18n',
],
snapshotSerializers: [
'enzyme-to-json/serializer',
],
moduleNameMapper: {
'^lodash-es$': 'lodash',
// This alias is for any code in the src directory that wants to avoid '../../' style relative imports:
'^@src/(.*)$': '<rootDir>/src/$1',
// This alias is used for plugins in the plugins/ folder only.
'^CourseAuthoring/(.*)$': '<rootDir>/src/$1',
},
modulePathIgnorePatterns: [
],
});

View File

@@ -1,11 +0,0 @@
# This file describes this Open edX repo, as described in OEP-2:
# http://open-edx-proposals.readthedocs.io/en/latest/oeps/oep-0002.html#specification
nick: cath
oeps: {}
owner: edx/platform-core-tnl
openedx-release:
# The openedx-release key is described in OEP-10:
# https://open-edx-proposals.readthedocs.io/en/latest/oep-0010-proc-openedx-releases.html
# The FAQ might also be helpful: https://openedx.atlassian.net/wiki/spaces/COMM/pages/1331268879/Open+edX+Release+FAQ
ref: master

51808
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,83 +1,125 @@
{
"name": "@edx/frontend-app-course-authoring",
"name": "@edx/frontend-app-authoring",
"version": "0.1.0",
"description": "Frontend application template",
"repository": {
"type": "git",
"url": "git+https://github.com/openedx/frontend-app-course-authoring.git"
"url": "git+https://github.com/openedx/frontend-app-authoring.git"
},
"browserslist": [
"extends @edx/browserslist-config"
],
"scripts": {
"build": "fedx-scripts webpack",
"i18n_extract": "BABEL_ENV=i18n fedx-scripts babel src --quiet > /dev/null",
"lint": "fedx-scripts eslint --ext .js --ext .jsx .",
"lint:fix": "fedx-scripts eslint --ext .js --ext .jsx . --fix",
"snapshot": "fedx-scripts jest --updateSnapshot",
"i18n_extract": "fedx-scripts formatjs extract --include=plugins",
"stylelint": "stylelint \"plugins/**/*.scss\" \"src/**/*.scss\" \"scss/**/*.scss\" --config .stylelintrc.json",
"lint": "npm run stylelint && fedx-scripts eslint --ext .js --ext .jsx --ext .ts --ext .tsx .",
"oxlint": "oxlint --type-aware --deny-warnings",
"lint:fix": "npm run stylelint -- --fix && fedx-scripts eslint --fix --ext .js --ext .jsx --ext .ts --ext .tsx .",
"start": "fedx-scripts webpack-dev-server --progress",
"test": "fedx-scripts jest --coverage --passWithNoTests"
},
"husky": {
"hooks": {
"pre-commit": "npm run lint"
}
"start:with-theme": "paragon install-theme && npm start && npm install",
"dev": "PUBLIC_PATH=/authoring/ MFE_CONFIG_API_URL='http://localhost:8000/api/mfe_config/v1' fedx-scripts webpack-dev-server --progress --host apps.local.openedx.io",
"test": "TZ=UTC fedx-scripts jest --coverage --passWithNoTests",
"test:ci": "TZ=UTC fedx-scripts jest --silent --coverage --passWithNoTests",
"types": "tsc --noEmit"
},
"author": "edX",
"license": "AGPL-3.0",
"homepage": "https://github.com/openedx/frontend-app-course-authoring#readme",
"homepage": "https://github.com/openedx/frontend-app-authoring#readme",
"publishConfig": {
"access": "public"
},
"bugs": {
"url": "https://github.com/openedx/frontend-app-course-authoring/issues"
"url": "https://github.com/openedx/frontend-app-authoring/issues"
},
"dependencies": {
"@edx/brand": "npm:@edx/brand-openedx@1.1.0",
"@edx/frontend-build": "^11.0.0",
"@edx/frontend-component-footer": "11.1.1",
"@edx/frontend-lib-content-components": "^1.43.0",
"@edx/frontend-platform": "2.5.1",
"@edx/paragon": "20.6.1",
"@fortawesome/fontawesome-svg-core": "1.2.28",
"@fortawesome/free-brands-svg-icons": "5.11.2",
"@fortawesome/free-regular-svg-icons": "5.11.2",
"@fortawesome/free-solid-svg-icons": "5.11.2",
"@fortawesome/react-fontawesome": "0.1.9",
"@reduxjs/toolkit": "1.5.0",
"classnames": "2.2.6",
"core-js": "3.8.1",
"@codemirror/lang-html": "^6.0.0",
"@codemirror/lang-markdown": "^6.0.0",
"@codemirror/lang-xml": "^6.0.0",
"@codemirror/lint": "^6.2.1",
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0",
"@dnd-kit/core": "^6.1.0",
"@dnd-kit/modifiers": "^7.0.0",
"@dnd-kit/sortable": "^8.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.3",
"@edx/browserslist-config": "1.5.1",
"@edx/frontend-component-footer": "^14.9.0",
"@edx/frontend-component-header": "^8.1.0",
"@edx/frontend-enterprise-hotjar": "^7.2.0",
"@edx/frontend-platform": "^8.4.0",
"@edx/openedx-atlas": "^0.7.0",
"@openedx-plugins/course-app-calculator": "file:plugins/course-apps/calculator",
"@openedx-plugins/course-app-edxnotes": "file:plugins/course-apps/edxnotes",
"@openedx-plugins/course-app-learning_assistant": "file:plugins/course-apps/learning_assistant",
"@openedx-plugins/course-app-live": "file:plugins/course-apps/live",
"@openedx-plugins/course-app-ora_settings": "file:plugins/course-apps/ora_settings",
"@openedx-plugins/course-app-proctoring": "file:plugins/course-apps/proctoring",
"@openedx-plugins/course-app-progress": "file:plugins/course-apps/progress",
"@openedx-plugins/course-app-teams": "file:plugins/course-apps/teams",
"@openedx-plugins/course-app-wiki": "file:plugins/course-apps/wiki",
"@openedx-plugins/course-app-xpert_unit_summary": "file:plugins/course-apps/xpert_unit_summary",
"@openedx/frontend-build": "^14.6.2",
"@openedx/frontend-plugin-framework": "^1.8.0",
"@openedx/paragon": "^23.5.0",
"@redux-devtools/extension": "^3.3.0",
"@reduxjs/toolkit": "2.11.2",
"@tanstack/react-query": "5.90.21",
"@tinymce/tinymce-react": "^6.0.0",
"classnames": "2.5.1",
"codemirror": "^6.0.0",
"email-validator": "2.0.4",
"formik": "2.2.6",
"lodash": "4.17.21",
"moment": "2.29.2",
"prop-types": "15.7.2",
"react": "16.14.0",
"react-dom": "16.14.0",
"react-redux": "7.1.3",
"react-responsive": "8.1.0",
"react-router": "5.1.2",
"react-router-dom": "5.1.2",
"react-transition-group": "4.4.1",
"redux": "4.0.5",
"regenerator-runtime": "0.13.7",
"uuid": "^3.4.0",
"yup": "0.31.1"
"fast-xml-parser": "^5.0.0",
"file-saver": "^2.0.5",
"formik": "2.4.9",
"frontend-components-tinymce-advanced-plugins": "^1.0.3",
"jszip": "^3.10.1",
"lodash": "4.17.23",
"meilisearch": "^0.41.0",
"moment": "2.30.1",
"moment-shortformat": "^2.1.0",
"prop-types": "^15.8.1",
"react": "^18.3.1",
"react-datepicker": "^8.10.0",
"react-dom": "^18.3.1",
"react-error-boundary": "^4.0.13",
"react-helmet": "^6.1.0",
"react-onclickoutside": "^6.13.0",
"react-redux": "7.2.9",
"react-responsive": "10.0.1",
"react-router": "6.30.3",
"react-router-dom": "6.30.3",
"react-select": "5.10.2",
"react-textarea-autosize": "^8.5.3",
"react-transition-group": "4.4.5",
"redux": "4.2.1",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.4.1",
"reselect": "^4.1.5",
"tinymce": "^5.10.4",
"universal-cookie": "^8.0.0",
"uuid": "^11.1.0",
"xmlchecker": "^0.1.0",
"yup": "0.32.11"
},
"devDependencies": {
"@edx/browserslist-config": "1.0.0",
"@edx/frontend-build": "^11.0.0",
"@edx/reactifex": "^1.0.3",
"@testing-library/jest-dom": "5.16.4",
"@testing-library/react": "12.1.1",
"@testing-library/user-event": "^13.2.1",
"axios-mock-adapter": "1.20.0",
"enzyme": "3.11.0",
"enzyme-adapter-react-16": "1.15.6",
"enzyme-to-json": "^3.6.2",
"glob": "7.1.6",
"husky": "3.1.0",
"react-test-renderer": "16.9.0",
"reactifex": "1.1.1"
"@edx/stylelint-config-edx": "2.3.3",
"@edx/typescript-config": "^1.0.1",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.2.0",
"@testing-library/user-event": "^14.6.1",
"@types/lodash": "^4.17.17",
"@types/react": "^18",
"@types/react-dom": "^18",
"axios-mock-adapter": "2.1.0",
"eslint-import-resolver-webpack": "^0.13.8",
"fetch-mock-jest": "^1.5.1",
"jest-canvas-mock": "^2.5.2",
"jest-expect-message": "^1.1.3",
"oxlint": "^1.42.0",
"oxlint-tsgolint": "^0.14.0",
"react-test-renderer": "^18.3.1",
"redux-mock-store": "^1.5.4"
}
}

View File

@@ -1,12 +1,17 @@
import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import AppSettingsModal from '../app-settings-modal/AppSettingsModal';
import AppSettingsModal from 'CourseAuthoring/pages-and-resources/app-settings-modal/AppSettingsModal';
import messages from './messages';
function CalculatorSettings({ intl, onClose }) {
/**
* Settings widget for the "calculator" Course App.
* @param {{onClose: () => void}} props
*/
const CalculatorSettings = ({ onClose }) => {
const intl = useIntl();
return (
<AppSettingsModal
appId="calculator"
@@ -17,11 +22,10 @@ function CalculatorSettings({ intl, onClose }) {
onClose={onClose}
/>
);
}
};
CalculatorSettings.propTypes = {
intl: intlShape.isRequired,
onClose: PropTypes.func.isRequired,
};
export default injectIntl(CalculatorSettings);
export default CalculatorSettings;

View File

@@ -0,0 +1,17 @@
{
"name": "@openedx-plugins/course-app-calculator",
"version": "0.1.0",
"description": "Calculator configuration for courses using it",
"peerDependencies": {
"@edx/frontend-app-authoring": "*",
"@edx/frontend-platform": "*",
"@openedx/paragon": "*",
"prop-types": "*",
"react": "*"
},
"peerDependenciesMeta": {
"@edx/frontend-app-authoring": {
"optional": true
}
}
}

View File

@@ -1,12 +1,17 @@
import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import AppSettingsModal from '../app-settings-modal/AppSettingsModal';
import AppSettingsModal from 'CourseAuthoring/pages-and-resources/app-settings-modal/AppSettingsModal';
import messages from './messages';
function NotesSettings({ intl, onClose }) {
/**
* Settings widget for the "edxnotes" Course App.
* @param {{onClose: () => void}} props
*/
const NotesSettings = ({ onClose }) => {
const intl = useIntl();
return (
<AppSettingsModal
appId="edxnotes"
@@ -17,11 +22,10 @@ function NotesSettings({ intl, onClose }) {
onClose={onClose}
/>
);
}
};
NotesSettings.propTypes = {
intl: intlShape.isRequired,
onClose: PropTypes.func.isRequired,
};
export default injectIntl(NotesSettings);
export default NotesSettings;

View File

@@ -0,0 +1,17 @@
{
"name": "@openedx-plugins/course-app-edxnotes",
"version": "0.1.0",
"description": "edxnotes configuration for courses using it",
"peerDependencies": {
"@edx/frontend-app-authoring": "*",
"@edx/frontend-platform": "*",
"@openedx/paragon": "*",
"prop-types": "*",
"react": "*"
},
"peerDependenciesMeta": {
"@edx/frontend-app-authoring": {
"optional": true
}
}
}

View File

@@ -0,0 +1,63 @@
import React from 'react';
import PropTypes from 'prop-types';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink } from '@openedx/paragon';
import AppSettingsModal from 'CourseAuthoring/pages-and-resources/app-settings-modal/AppSettingsModal';
import { useModel } from 'CourseAuthoring/generic/model-store';
import messages from './messages';
const LearningAssistantSettings = ({ onClose }) => {
const appId = 'learning_assistant';
const appInfo = useModel('courseApps', appId);
const intl = useIntl();
// We need to render more than one link, so we use the bodyChildren prop.
const bodyChildren = (
appInfo?.documentationLinks?.learnMoreOpenaiDataPrivacy && appInfo?.documentationLinks?.learnMoreOpenai
? (
<div className="d-flex flex-column">
{appInfo.documentationLinks?.learnMoreOpenaiDataPrivacy && (
<Hyperlink
className="text-primary-500"
destination={appInfo.documentationLinks.learnMoreOpenaiDataPrivacy}
target="_blank"
rel="noreferrer noopener"
>
{intl.formatMessage(messages.learningAssistantOpenAIDataPrivacyLink)}
</Hyperlink>
)}
{appInfo.documentationLinks?.learnMoreOpenai && (
<Hyperlink
className="text-primary-500"
destination={appInfo.documentationLinks.learnMoreOpenai}
target="_blank"
rel="noreferrer noopener"
>
{intl.formatMessage(messages.learningAssistantOpenAILink)}
</Hyperlink>
)}
</div>
)
: null
);
return (
<AppSettingsModal
appId={appId}
title={intl.formatMessage(messages.heading)}
enableAppHelp={intl.formatMessage(messages.enableLearningAssistantHelp)}
enableAppLabel={intl.formatMessage(messages.enableLearningAssistantLabel)}
bodyChildren={bodyChildren}
onClose={onClose}
/>
);
};
LearningAssistantSettings.propTypes = {
onClose: PropTypes.func.isRequired,
};
export default LearningAssistantSettings;

View File

@@ -0,0 +1,49 @@
import React from 'react';
import { screen, waitFor } from '@testing-library/react';
import { RequestStatus } from 'CourseAuthoring/data/constants';
import { initializeMocks, render } from 'CourseAuthoring/testUtils';
import LearningAssistantSettings from './Settings';
const onClose = () => { };
describe('Learning Assistant Settings', () => {
it('renders', async () => {
const initialState = {
models: {
courseApps: {
learning_assistant:
{
id: 'learning_assistant',
enabled: true,
name: 'Learning Assistant',
description: 'Learning Assistant description',
allowedOperations: {
configure: false,
enable: true,
},
documentationLinks: {
learnMoreOpenaiDataPrivacy: 'www.example.com/learn-more-data-privacy',
learnMoreOpenai: 'www.example.com/learn-more',
},
},
},
},
pagesAndResources: {
loadingStatus: RequestStatus.SUCCESSFUL,
},
};
initializeMocks({ initialState });
render(<LearningAssistantSettings onClose={onClose} />);
const toggleDescription = 'Reinforce learning concepts by sharing text-based course content '
+ 'with OpenAI (via API) to power an in-course Learning Assistant. Learners can leave feedback about the quality '
+ 'of the AI-powered experience for use by edX to improve the performance of the tool.';
await waitFor(() => expect(screen.getByRole('heading', { name: 'Configure Learning Assistant' })).toBeInTheDocument());
await waitFor(() => expect(screen.getByText(toggleDescription)).toBeInTheDocument());
await waitFor(() => expect(screen.getByText('Learn more about how OpenAI handles data')).toBeInTheDocument());
await waitFor(() => expect(screen.getByText('Learn more about OpenAI API data privacy')).toBeInTheDocument());
});
});

View File

@@ -0,0 +1,28 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
heading: {
id: 'course-authoring.pages-resources.learning-assistant.heading',
defaultMessage: 'Configure Learning Assistant',
},
enableLearningAssistantLabel: {
id: 'course-authoring.pages-resources.learning_assistant.enable-learning-assistant.label',
defaultMessage: 'Learning Assistant',
},
enableLearningAssistantHelp: {
id: 'course-authoring.pages-resources.learning_assistant.enable-learning-assistant.help',
defaultMessage: `Reinforce learning concepts by sharing text-based course content with OpenAI (via API) to power
an in-course Learning Assistant. Learners can leave feedback about the quality of the AI-powered experience for
use by edX to improve the performance of the tool.`,
},
learningAssistantOpenAILink: {
id: 'course-authoring.pages-resources.learning_assistant.open-ai.link',
defaultMessage: 'Learn more about how OpenAI handles data',
},
learningAssistantOpenAIDataPrivacyLink: {
id: 'course-authoring.pages-resources.learning_assistant.open-ai.data-privacy.link',
defaultMessage: 'Learn more about OpenAI API data privacy',
},
});
export default messages;

View File

@@ -0,0 +1,19 @@
{
"name": "@openedx-plugins/course-app-learning_assistant",
"version": "0.1.0",
"description": "Learning Assistant configuration for courses using it",
"peerDependencies": {
"@edx/frontend-app-authoring": "*",
"@edx/frontend-platform": "*",
"@openedx/paragon": "*",
"prop-types": "*",
"react": "*",
"yup": "*"
},
"peerDependenciesMeta": {
"@edx/frontend-app-authoring": {
"optional": true
}
}
}

View File

@@ -1,25 +1,26 @@
import React, { useEffect, useState } from 'react';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { Form, Hyperlink } from '@edx/paragon';
import { getConfig, getExternalLinkUrl } from '@edx/frontend-platform';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Form, Hyperlink } from '@openedx/paragon';
import PropTypes from 'prop-types';
import messages from './messages';
import { providerNames, bbbPlanTypes } from './constants';
import AppConfigFormDivider from '../discussions/app-config-form/apps/shared/AppConfigFormDivider';
import LiveCommonFields from './LiveCommonFields';
import { useModel } from '../../generic/model-store';
import AppConfigFormDivider from 'CourseAuthoring/pages-and-resources/discussions/app-config-form/apps/shared/AppConfigFormDivider';
import { useModel } from 'CourseAuthoring/generic/model-store';
function BbbSettings({
intl,
import { providerNames, bbbPlanTypes } from './constants';
import LiveCommonFields from './LiveCommonFields';
import messages from './messages';
const BbbSettings = ({
values,
setFieldValue,
}) {
}) => {
const intl = useIntl();
const [bbbPlan, setBbbPlan] = useState(values.tierType);
useEffect(() => {
setBbbPlan(values.tierType);
}, [values.tierType]);
const appInfo = useModel('courseApps', 'live');
const app = useModel('liveApps', 'big_blue_button');
const isPiiDisabled = !values.piiSharingEnable;
function getBbbPlanOptions() {
@@ -71,7 +72,7 @@ function BbbSettings({
</Form.Group>
<Hyperlink
destination={appInfo.documentationLinks.learnMoreConfiguration}
destination={getConfig().BBB_LEARN_MORE_URL}
target="_blank"
rel="noopener noreferrer"
showLaunchIcon
@@ -88,22 +89,28 @@ function BbbSettings({
) : (
<>
{bbbPlan === bbbPlanTypes.commercial && <LiveCommonFields values={values} />}
{bbbPlan === bbbPlanTypes.free
&& (
<p data-testid="free-plan-message">
{bbbPlan === bbbPlanTypes.free && (
<span data-testid="free-plan-message">
{intl.formatMessage(messages.freePlanMessage)}
</p>
<Hyperlink
destination={getExternalLinkUrl('https://bigbluebutton.org/privacy-policy/')}
target="_blank"
rel="noopener noreferrer"
showLaunchIcon
className="text-gray-700 ml-1"
>
{intl.formatMessage(messages.privacyPolicy)}
</Hyperlink>
</span>
)}
</>
)}
</>
</>
);
}
};
BbbSettings.propTypes = {
intl: intlShape.isRequired,
values: PropTypes.shape({
consumerKey: PropTypes.string,
consumerSecret: PropTypes.string,
@@ -118,4 +125,4 @@ BbbSettings.propTypes = {
setFieldValue: PropTypes.func.isRequired,
};
export default injectIntl(BbbSettings);
export default BbbSettings;

View File

@@ -4,18 +4,16 @@ import {
getByRole,
getAllByRole,
waitForElementToBeRemoved,
} from '@testing-library/react';
initializeMocks,
} from 'CourseAuthoring/testUtils';
import { Switch } from 'react-router-dom';
import { initializeMockApp, history } from '@edx/frontend-platform';
import MockAdapter from 'axios-mock-adapter';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { AppProvider, PageRoute } from '@edx/frontend-platform/react';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import ReactDOM from 'react-dom';
import userEvent from '@testing-library/user-event';
import initializeStore from '../../store';
import { executeThunk } from '../../utils';
import { executeThunk } from 'CourseAuthoring/utils';
import PagesAndResourcesProvider from 'CourseAuthoring/pages-and-resources/PagesAndResourcesProvider';
import { CourseAuthoringProvider } from 'CourseAuthoring/CourseAuthoringContext';
import LiveSettings from './Settings';
import {
generateLiveConfigurationApiResponse,
@@ -23,40 +21,44 @@ import {
initialState,
configurationProviders,
} from './factories/mockApiResponses';
import { fetchLiveConfiguration, fetchLiveProviders } from './data/thunks';
import { providerConfigurationApiUrl, providersApiUrl } from './data/api';
import messages from './messages';
import PagesAndResourcesProvider from '../PagesAndResourcesProvider';
let axiosMock;
let container;
let store;
const liveSettingsUrl = `/course/${courseId}/pages-and-resources/live/settings`;
// Modal creates a portal. Overriding ReactDOM.createPortal allows portals to be tested in jest.
ReactDOM.createPortal = jest.fn(node => node);
const renderComponent = () => {
const wrapper = render(
<IntlProvider locale="en">
<AppProvider store={store}>
<PagesAndResourcesProvider courseId={courseId}>
<Switch>
<PageRoute path={liveSettingsUrl}>
<LiveSettings onClose={() => {}} />
</PageRoute>
</Switch>
</PagesAndResourcesProvider>
</AppProvider>
</IntlProvider>,
<CourseAuthoringProvider courseId={courseId}>
<PagesAndResourcesProvider courseId={courseId}>
<LiveSettings onClose={() => {}} />
</PagesAndResourcesProvider>
</CourseAuthoringProvider>,
{
path: liveSettingsUrl,
routerProps: {
initialEntries: [liveSettingsUrl],
},
params: {
courseId,
},
},
);
container = wrapper.container;
};
const mockStore = async ({
usernameSharing = false,
emailSharing = false,
enabled = true,
piiSharingAllowed = true,
isFreeTier = false,
usernameSharing = false,
emailSharing = false,
enabled = true,
piiSharingAllowed = true,
isFreeTier = false,
}) => {
const fetchProviderConfigUrl = `${providersApiUrl}/${courseId}/`;
const fetchLiveConfigUrl = `${providerConfigurationApiUrl}/${courseId}/`;
@@ -70,17 +72,9 @@ const mockStore = async ({
describe('BBB Settings', () => {
beforeEach(async () => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: false,
roles: [],
},
});
store = initializeStore(initialState);
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
history.push(liveSettingsUrl);
const mocks = initializeMocks({ initialState });
store = mocks.reduxStore;
axiosMock = mocks.axiosMock;
});
test('Plan dropdown to be visible and enabled in UI', async () => {
@@ -103,7 +97,8 @@ describe('BBB Settings', () => {
expect(getAllByRole(dropDown, 'option').length).toBe(noOfOptions);
});
test('Connect to support and PII sharing message is visible and plans selection is disabled, When pii sharing is disabled, ',
test(
'Connect to support and PII sharing message is visible and plans selection is disabled, When pii sharing is disabled, ',
async () => {
await mockStore({ piiSharingAllowed: false });
renderComponent();
@@ -116,17 +111,19 @@ describe('BBB Settings', () => {
);
expect(helpRequestPiiText).toHaveTextContent(messages.piiSharingEnableHelpTextBbb.defaultMessage);
expect(container.querySelector('select[name="tierType"]')).toBeDisabled();
});
},
);
test('free plans message is visible when free plan is selected', async () => {
const user = userEvent.setup();
await mockStore({ emailSharing: true, isFreeTier: true });
renderComponent();
const spinner = getByRole(container, 'status');
await waitForElementToBeRemoved(spinner);
const dropDown = container.querySelector('select[name="tierType"]');
userEvent.selectOptions(
await user.selectOptions(
dropDown,
getByRole(dropDown, 'option', { name: 'Free' }),
getByRole(dropDown, 'option', { name: 'Free' }),
);
expect(queryByTestId(container, 'free-plan-message')).toBeInTheDocument();
expect(queryByTestId(container, 'free-plan-message')).toHaveTextContent(messages.freePlanMessage.defaultMessage);

View File

@@ -1,13 +1,14 @@
import React from 'react';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import PropTypes from 'prop-types';
import messages from './messages';
import FormikControl from '../../generic/FormikControl';
import FormikControl from 'CourseAuthoring/generic/FormikControl';
function LiveCommonFields({
intl,
values,
}) {
import messages from './messages';
const LiveCommonFields = ({
values,
}) => {
const intl = useIntl();
return (
<>
<p className="pb-2">{intl.formatMessage(messages.formInstructions)}</p>
@@ -34,10 +35,9 @@ function LiveCommonFields({
/>
</>
);
}
};
LiveCommonFields.propTypes = {
intl: intlShape.isRequired,
values: PropTypes.shape({
consumerKey: PropTypes.string,
consumerSecret: PropTypes.string,
@@ -46,4 +46,4 @@ LiveCommonFields.propTypes = {
}).isRequired,
};
export default injectIntl(LiveCommonFields);
export default LiveCommonFields;

View File

@@ -0,0 +1,139 @@
// oxlint-disable unicorn/no-thenable
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { camelCase } from 'lodash';
import { Icon } from '@openedx/paragon';
import { useIntl } from '@edx/frontend-platform/i18n';
import PropTypes from 'prop-types';
import * as Yup from 'yup';
import { useNavigate } from 'react-router-dom';
import SelectableBox from 'CourseAuthoring/editors/sharedComponents/SelectableBox';
import AppSettingsModal from 'CourseAuthoring/pages-and-resources/app-settings-modal/AppSettingsModal';
import { useModel } from 'CourseAuthoring/generic/model-store';
import Loading from 'CourseAuthoring/generic/Loading';
import { RequestStatus } from 'CourseAuthoring/data/constants';
import { useCourseAuthoringContext } from 'CourseAuthoring/CourseAuthoringContext';
import { fetchLiveData, saveLiveConfiguration, saveLiveConfigurationAsDraft } from './data/thunks';
import { selectApp } from './data/slice';
import { iconsSrc, bbbPlanTypes } from './constants';
import messages from './messages';
import ZoomSettings from './ZoomSettings';
import BBBSettings from './BBBSettings';
const LiveSettings = ({
onClose,
}) => {
const intl = useIntl();
const navigate = useNavigate();
const dispatch = useDispatch();
const { courseId } = useCourseAuthoringContext();
const availableProviders = useSelector((state) => state.live.appIds);
const {
piiSharingAllowed, selectedAppId, enabled, status,
} = useSelector(state => state.live);
const appConfig = useModel('liveAppConfigs', selectedAppId);
const app = useModel('liveApps', selectedAppId);
const liveConfiguration = {
enabled: enabled || false,
consumerKey: appConfig?.consumerKey || '',
consumerSecret: appConfig?.consumerSecret || '',
launchUrl: appConfig?.launchUrl || '',
launchEmail: appConfig?.launchEmail || '',
provider: selectedAppId || 'zoom',
piiSharingEnable: piiSharingAllowed || false,
piiSharingUsername: app?.piiSharing?.username || false,
piiSharingEmail: app?.piiSharing?.email || false,
tierType: appConfig?.tierType || '',
};
const validationSchema = {
enabled: Yup.boolean(),
consumerKey: Yup.string().when(['provider', 'tierType'], {
is: (provider, tier) => provider === 'zoom' || (provider === 'big_blue_button' && tier === bbbPlanTypes.commercial),
then: Yup.string().required(intl.formatMessage(messages.consumerKeyRequired)),
}),
consumerSecret: Yup.string().when(['provider', 'tierType'], {
is: (provider, tier) => provider === 'zoom' || (provider === 'big_blue_button' && tier === bbbPlanTypes.commercial),
then: Yup.string().notRequired(intl.formatMessage(messages.consumerSecretRequired)),
}),
launchUrl: Yup.string().when(['provider', 'tierType'], {
is: (provider, tier) => provider === 'zoom' || (provider === 'big_blue_button' && tier === bbbPlanTypes.commercial),
then: Yup.string().required(intl.formatMessage(messages.launchUrlRequired)),
}),
launchEmail: Yup.string(),
};
const handleProviderChange = (providerId, setFieldValue, values) => {
dispatch(saveLiveConfigurationAsDraft(values));
dispatch(selectApp({ appId: providerId }));
setFieldValue('provider', providerId);
};
const handleSettingsSave = async (values) => {
// oxlint-disable-next-line @typescript-eslint/await-thenable - this dispatch() IS returning a promise.
await dispatch(saveLiveConfiguration(courseId, values, navigate));
};
useEffect(() => {
dispatch(fetchLiveData(courseId));
}, [courseId]);
return (
<AppSettingsModal
appId="live"
title={intl.formatMessage(messages.heading)}
enableAppHelp={intl.formatMessage(messages.enableLiveHelp)}
enableAppLabel={intl.formatMessage(messages.enableLiveLabel)}
learnMoreText={intl.formatMessage(messages.enableLiveLink)}
onClose={onClose}
initialValues={liveConfiguration}
validationSchema={validationSchema}
onSettingsSave={handleSettingsSave}
configureBeforeEnable
enableReinitialize
>
{({ values, setFieldValue }) => (
(status === RequestStatus.IN_PROGRESS) ? (
<Loading />
) : (
<>
<h4 className="my-3">{intl.formatMessage(messages.selectProvider)}</h4>
<SelectableBox.Set
type="checkbox"
value={values.provider}
onChange={(event) => handleProviderChange(event.target.value, setFieldValue, values)}
name="provider"
columns={3}
className="mb-3"
>
{availableProviders.map((provider) => (
<SelectableBox value={provider} type="checkbox" key={provider}>
<div className="d-flex flex-column align-items-center">
<Icon src={iconsSrc[`${camelCase(provider)}`]} alt={provider} />
<span>{intl.formatMessage(messages[`appName-${camelCase(provider)}`])}</span>
</div>
</SelectableBox>
))}
</SelectableBox.Set>
{values.provider === 'zoom' ? <ZoomSettings values={values} />
: (
<BBBSettings
values={values}
setFieldValue={setFieldValue}
/>
)}
</>
)
)}
</AppSettingsModal>
);
};
LiveSettings.propTypes = {
onClose: PropTypes.func.isRequired,
};
export default LiveSettings;

View File

@@ -8,17 +8,14 @@ import {
queryByText,
getByRole,
waitForElementToBeRemoved,
} from '@testing-library/react';
initializeMocks,
} from 'CourseAuthoring/testUtils';
import { Switch } from 'react-router-dom';
import { initializeMockApp, history } from '@edx/frontend-platform';
import MockAdapter from 'axios-mock-adapter';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { AppProvider, PageRoute } from '@edx/frontend-platform/react';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import ReactDOM from 'react-dom';
import { executeThunk } from 'CourseAuthoring/utils';
import PagesAndResourcesProvider from 'CourseAuthoring/pages-and-resources/PagesAndResourcesProvider';
import initializeStore from '../../store';
import { executeThunk } from '../../utils';
import { CourseAuthoringProvider } from 'CourseAuthoring/CourseAuthoringContext';
import LiveSettings from './Settings';
import {
generateLiveConfigurationApiResponse,
@@ -30,35 +27,40 @@ import {
import { fetchLiveConfiguration, fetchLiveProviders } from './data/thunks';
import { providerConfigurationApiUrl, providersApiUrl } from './data/api';
import messages from './messages';
import PagesAndResourcesProvider from '../PagesAndResourcesProvider';
let axiosMock;
let container;
let store;
const liveSettingsUrl = `/course/${courseId}/pages-and-resources/live/settings`;
// Modal creates a portal. Overriding ReactDOM.createPortal allows portals to be tested in jest.
ReactDOM.createPortal = jest.fn(node => node);
const renderComponent = () => {
const wrapper = render(
<IntlProvider locale="en">
<AppProvider store={store}>
<PagesAndResourcesProvider courseId={courseId}>
<Switch>
<PageRoute path={liveSettingsUrl}>
<LiveSettings onClose={() => {}} />
</PageRoute>
</Switch>
</PagesAndResourcesProvider>
</AppProvider>
</IntlProvider>,
<PagesAndResourcesProvider courseId={courseId}>
<CourseAuthoringProvider>
<LiveSettings onClose={() => {}} />
</CourseAuthoringProvider>
</PagesAndResourcesProvider>,
{
path: liveSettingsUrl,
routerProps: {
initialEntries: [liveSettingsUrl],
},
params: {
courseId,
},
},
);
container = wrapper.container;
};
const mockStore = async ({
usernameSharing = false,
emailSharing = false,
enabled = true,
piiSharingAllowed = true,
usernameSharing = false,
emailSharing = false,
enabled = true,
piiSharingAllowed = true,
}) => {
const fetchProviderConfigUrl = `${providersApiUrl}/${courseId}/`;
const fetchLiveConfigUrl = `${providerConfigurationApiUrl}/${courseId}/`;
@@ -72,17 +74,11 @@ const mockStore = async ({
describe('LiveSettings', () => {
beforeEach(async () => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: false,
roles: [],
},
const mocks = initializeMocks({
initialState,
});
store = initializeStore(initialState);
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
history.push(liveSettingsUrl);
store = mocks.reduxStore;
axiosMock = mocks.axiosMock;
});
test('Live Configuration modal is visible', async () => {

View File

@@ -1,29 +1,31 @@
import React from 'react';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import PropTypes from 'prop-types';
import FormikControl from 'CourseAuthoring/generic/FormikControl';
import messages from './messages';
import { providerNames } from './constants';
import LiveCommonFields from './LiveCommonFields';
import FormikControl from '../../generic/FormikControl';
function ZoomsSettings({
intl,
values,
}) {
const ZoomSettings = ({
values,
}) => {
const intl = useIntl();
return (
// eslint-disable-next-line react/jsx-no-useless-fragment
<>
{(!values.piiSharingEnable && (values.piiSharingEmail || values.piiSharingUsername)) ? (
{!values.piiSharingEnable ? (
<p data-testid="request-pii-sharing">
{intl.formatMessage(messages.requestPiiSharingEnable, { provider: providerNames[values.provider] })}
</p>
) : (
<>
{(values.piiSharingEmail || values.piiSharingUsername)
&& (
<p data-testid="helper-text">
{intl.formatMessage(messages.providerHelperText, { providerName: providerNames[values.provider] })}
</p>
)}
&& (
<p data-testid="helper-text">
{intl.formatMessage(messages.providerHelperText, { providerName: providerNames[values.provider] })}
</p>
)}
<LiveCommonFields values={values} />
<FormikControl
name="launchEmail"
@@ -35,10 +37,9 @@ function ZoomsSettings({
)}
</>
);
}
};
ZoomsSettings.propTypes = {
intl: intlShape.isRequired,
ZoomSettings.propTypes = {
values: PropTypes.shape({
consumerKey: PropTypes.string,
consumerSecret: PropTypes.string,
@@ -51,4 +52,4 @@ ZoomsSettings.propTypes = {
}).isRequired,
};
export default injectIntl(ZoomsSettings);
export default ZoomSettings;

View File

@@ -3,17 +3,14 @@ import {
queryByTestId,
getByRole,
waitForElementToBeRemoved,
} from '@testing-library/react';
initializeMocks,
} from 'CourseAuthoring/testUtils';
import { Switch } from 'react-router-dom';
import { initializeMockApp, history } from '@edx/frontend-platform';
import MockAdapter from 'axios-mock-adapter';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { AppProvider, PageRoute } from '@edx/frontend-platform/react';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import ReactDOM from 'react-dom';
import initializeStore from '../../store';
import { executeThunk } from '../../utils';
import { executeThunk } from 'CourseAuthoring/utils';
import PagesAndResourcesProvider from 'CourseAuthoring/pages-and-resources/PagesAndResourcesProvider';
import { CourseAuthoringProvider } from 'CourseAuthoring/CourseAuthoringContext';
import LiveSettings from './Settings';
import {
generateLiveConfigurationApiResponse,
@@ -25,35 +22,40 @@ import {
import { fetchLiveConfiguration, fetchLiveProviders } from './data/thunks';
import { providerConfigurationApiUrl, providersApiUrl } from './data/api';
import messages from './messages';
import PagesAndResourcesProvider from '../PagesAndResourcesProvider';
let axiosMock;
let container;
let store;
const liveSettingsUrl = `/course/${courseId}/pages-and-resources/live/settings`;
// Modal creates a portal. Overriding ReactDOM.createPortal allows portals to be tested in jest.
ReactDOM.createPortal = jest.fn(node => node);
const renderComponent = () => {
const wrapper = render(
<IntlProvider locale="en">
<AppProvider store={store}>
<PagesAndResourcesProvider courseId={courseId}>
<Switch>
<PageRoute path={liveSettingsUrl}>
<LiveSettings onClose={() => {}} />
</PageRoute>
</Switch>
</PagesAndResourcesProvider>
</AppProvider>
</IntlProvider>,
<CourseAuthoringProvider courseId={courseId}>
<PagesAndResourcesProvider courseId={courseId}>
<LiveSettings onClose={() => {}} />
</PagesAndResourcesProvider>
</CourseAuthoringProvider>,
{
path: liveSettingsUrl,
routerProps: {
initialEntries: [liveSettingsUrl],
},
params: {
courseId,
},
},
);
container = wrapper.container;
};
const mockStore = async ({
usernameSharing = false,
emailSharing = false,
enabled = true,
piiSharingAllowed = true,
usernameSharing = false,
emailSharing = false,
enabled = true,
piiSharingAllowed = true,
}) => {
const fetchProviderConfigUrl = `${providersApiUrl}/${courseId}/`;
const fetchLiveConfigUrl = `${providerConfigurationApiUrl}/${courseId}/`;
@@ -67,21 +69,13 @@ const mockStore = async ({
describe('Zoom Settings', () => {
beforeEach(async () => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: false,
roles: [],
},
});
store = initializeStore(initialState);
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
history.push(liveSettingsUrl);
const mocks = initializeMocks({ initialState });
store = mocks.reduxStore;
axiosMock = mocks.axiosMock;
});
test('LTI fields are visible when pii sharing is enabled and email or username sharing required', async () => {
await mockStore({ emailSharing: true });
test('LTI fields are visible when pii sharing is enabled', async () => {
await mockStore({ piiSharingAllowed: true });
renderComponent();
const spinner = getByRole(container, 'status');
@@ -103,9 +97,9 @@ describe('Zoom Settings', () => {
});
test(
'Only connect to support message is visible when pii sharing is disabled and email or username sharing is required',
'Only connect to support message is visible when pii sharing is disabled',
async () => {
await mockStore({ emailSharing: true, piiSharingAllowed: false });
await mockStore({ piiSharingAllowed: false });
renderComponent();
const spinner = getByRole(container, 'status');
@@ -129,7 +123,7 @@ describe('Zoom Settings', () => {
test('Provider Configuration should be displayed correctly', async () => {
const apiDefaultResponse = generateLiveConfigurationApiResponse(true, true);
await mockStore({ emailSharing: false, piiSharingAllowed: false });
await mockStore({ piiSharingAllowed: true });
renderComponent();
const spinner = getByRole(container, 'status');

View File

@@ -1,6 +1,6 @@
import {
GoogleMeet, MicrosoftTeams, Zoom, Bbb,
} from '@edx/paragon/icons';
GoogleMeet, MicrosoftTeams, Zoom, Bbb,
} from '@openedx/paragon/icons';
export const iconsSrc = {
googleMeet: GoogleMeet,

View File

@@ -1,4 +1,3 @@
/* eslint-disable import/prefer-default-export */
import { ensureConfig, getConfig } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { bbbPlanTypes } from '../constants';

View File

@@ -1,6 +1,6 @@
/* eslint-disable no-param-reassign */
import { createSlice } from '@reduxjs/toolkit';
import { RequestStatus } from '../../../data/constants';
import { RequestStatus } from 'CourseAuthoring/data/constants';
const slice = createSlice({
name: 'live',

View File

@@ -1,14 +1,14 @@
import { history } from '@edx/frontend-platform';
import { addModel, addModels, updateModel } from '../../../generic/model-store';
import { addModel, addModels, updateModel } from 'CourseAuthoring/generic/model-store';
import { RequestStatus } from 'CourseAuthoring/data/constants';
import {
getLiveConfiguration,
getLiveProviders,
postLiveConfiguration,
normalizeSettings,
deNormalizeSettings,
getLiveConfiguration,
getLiveProviders,
postLiveConfiguration,
normalizeSettings,
deNormalizeSettings,
} from './api';
import { loadApps, updateStatus, updateSaveStatus } from './slice';
import { RequestStatus } from '../../../data/constants';
function updateLiveSettingsState({
appConfig,
@@ -56,7 +56,7 @@ export function fetchLiveData(courseId) {
};
}
export function saveLiveConfiguration(courseId, config) {
export function saveLiveConfiguration(courseId, config, navigate) {
return async (dispatch) => {
dispatch(updateSaveStatus({ status: RequestStatus.IN_PROGRESS }));
try {
@@ -64,7 +64,7 @@ export function saveLiveConfiguration(courseId, config) {
dispatch(updateLiveSettingsState(apps));
dispatch(updateSaveStatus({ status: RequestStatus.SUCCESSFUL }));
history.push(`/course/${courseId}/pages-and-resources/`);
navigate(`/course/${courseId}/pages-and-resources/`);
} catch (error) {
if (error.response && error.response.status === 403) {
dispatch(updateSaveStatus({ status: RequestStatus.DENIED }));

View File

@@ -36,11 +36,11 @@ export const initialState = {
export const configurationProviders = (
emailSharing,
usernameSharing,
activeProvider = 'zoom',
activeProvider,
hasFreeTier,
) => ({
providers: {
active: activeProvider,
active: activeProvider || 'zoom',
available: {
zoom: {
features: [],
@@ -65,7 +65,7 @@ export const generateLiveConfigurationApiResponse = (
enabled,
piiSharingAllowed,
providerType = 'zoom',
isFreeTier,
isFreeTier = undefined,
) => ({
course_key: courseId,
enabled,

View File

@@ -160,9 +160,14 @@ const messages = defineMessages({
freePlanMessage: {
id: 'authoring.live.freePlanMessage',
defaultMessage: 'The free plan is pre-configured, and no additional configurations are required.',
defaultMessage: 'The free plan is pre-configured, and no additional configurations are required. By selecting the free plan, you are agreeing to Blindside Networks',
description: 'Tells user that free plans requires no additional configurations',
},
privacyPolicy: {
id: 'authoring.live.privacyPolicy',
defaultMessage: 'Privacy Policy.',
description: 'The text of privacy policy hyperlink for free plan',
},
});
export default messages;

View File

@@ -0,0 +1,22 @@
{
"name": "@openedx-plugins/course-app-live",
"version": "0.1.0",
"description": "Live course configuration for courses using it",
"peerDependencies": {
"@edx/frontend-app-authoring": "*",
"@edx/frontend-platform": "*",
"@openedx/paragon": "*",
"@reduxjs/toolkit": "*",
"lodash": "*",
"prop-types": "*",
"react": "*",
"react-redux": "*",
"react-router-dom": "*",
"yup": "*"
},
"peerDependenciesMeta": {
"@edx/frontend-app-authoring": {
"optional": true
}
}
}

View File

@@ -0,0 +1,177 @@
import { useEffect, useState, useRef } from 'react';
import PropTypes from 'prop-types';
import { useIntl } from '@edx/frontend-platform/i18n';
import { useDispatch, useSelector } from 'react-redux';
import {
ActionRow, Alert, Badge, Form, Hyperlink, ModalDialog, StatefulButton,
} from '@openedx/paragon';
import { Info } from '@openedx/paragon/icons';
import { updateModel, useModel } from 'CourseAuthoring/generic/model-store';
import { RequestStatus } from 'CourseAuthoring/data/constants';
import FormSwitchGroup from 'CourseAuthoring/generic/FormSwitchGroup';
import Loading from 'CourseAuthoring/generic/Loading';
import PermissionDeniedAlert from 'CourseAuthoring/generic/PermissionDeniedAlert';
import ConnectionErrorAlert from 'CourseAuthoring/generic/ConnectionErrorAlert';
import { useAppSetting, useIsMobile } from 'CourseAuthoring/utils';
import { getLoadingStatus, getSavingStatus } from 'CourseAuthoring/pages-and-resources/data/selectors';
import { updateSavingStatus } from 'CourseAuthoring/pages-and-resources/data/slice';
import messages from './messages';
const ORASettings = ({ onClose }) => {
const dispatch = useDispatch();
const { formatMessage } = useIntl();
const alertRef = useRef(null);
const updateSettingsRequestStatus = useSelector(getSavingStatus);
const loadingStatus = useSelector(getLoadingStatus);
const isMobile = useIsMobile();
const modalVariant = isMobile ? 'dark' : 'default';
const appId = 'ora_settings';
const appInfo = useModel('courseApps', appId);
const [enableFlexiblePeerGrade, saveSetting] = useAppSetting(
'forceOnFlexiblePeerOpenassessments',
);
const initialFormValues = { enableFlexiblePeerGrade };
const [formValues, setFormValues] = useState(initialFormValues);
const [saveError, setSaveError] = useState(false);
const submitButtonState = updateSettingsRequestStatus === RequestStatus.IN_PROGRESS ? 'pending' : 'default';
const handleSettingsSave = (values) => saveSetting(values.enableFlexiblePeerGrade);
const handleSubmit = async (event) => {
let success = true;
event.preventDefault();
success = success && await handleSettingsSave(formValues);
setSaveError(!success);
if ((initialFormValues.enableFlexiblePeerGrade !== formValues.enableFlexiblePeerGrade) && success) {
// oxlint-disable-next-line @typescript-eslint/await-thenable - this dispatch() IS returning a promise.
success = await dispatch(updateModel({
modelType: 'courseApps',
model: {
id: appId, enabled: formValues.enableFlexiblePeerGrade,
},
}));
}
!success && alertRef?.current.scrollIntoView(); // eslint-disable-line @typescript-eslint/no-unused-expressions
};
const handleChange = (e) => {
setFormValues({ enableFlexiblePeerGrade: e.target.checked });
};
useEffect(() => {
if (updateSettingsRequestStatus === RequestStatus.SUCCESSFUL) {
dispatch(updateSavingStatus({ status: '' }));
onClose();
}
}, [updateSettingsRequestStatus]);
const renderBody = () => {
switch (loadingStatus) {
case RequestStatus.SUCCESSFUL:
return (
<>
{saveError && (
<Alert variant="danger" icon={Info} ref={alertRef}>
<Alert.Heading>
{formatMessage(messages.errorSavingTitle)}
</Alert.Heading>
{formatMessage(messages.errorSavingMessage)}
</Alert>
)}
<FormSwitchGroup
id="enable-flexible-peer-grade"
name="enableFlexiblePeerGrade"
label={(
<div className="d-flex align-items-center">
{formatMessage(messages.enableFlexPeerGradeLabel)}
{formValues.enableFlexiblePeerGrade && (
<Badge className="ml-2" variant="success" data-testid="enable-badge">
{formatMessage(messages.enabledBadgeLabel)}
</Badge>
)}
</div>
)}
helpText={(
<div>
<p>{formatMessage(messages.enableFlexPeerGradeHelp)}</p>
<span className="py-3">
<Hyperlink
className="text-primary-500 small"
destination={appInfo.documentationLinks?.learnMoreConfiguration}
target="_blank"
rel="noreferrer noopener"
>
{formatMessage(messages.ORASettingsHelpLink)}
</Hyperlink>
</span>
</div>
)}
onChange={handleChange}
checked={formValues.enableFlexiblePeerGrade}
/>
</>
);
case RequestStatus.DENIED:
return <PermissionDeniedAlert />;
case RequestStatus.FAILED:
return <ConnectionErrorAlert />;
default:
return <Loading />;
}
};
return (
<ModalDialog
title={formatMessage(messages.heading)}
isOpen
onClose={onClose}
size="lg"
variant={modalVariant}
hasCloseButton={isMobile}
isFullscreenScroll
isFullscreenOnMobile
>
<Form onSubmit={handleSubmit} data-testid="proctoringForm">
<ModalDialog.Header>
<ModalDialog.Title>
{formatMessage(messages.heading)}
</ModalDialog.Title>
</ModalDialog.Header>
<ModalDialog.Body>
{renderBody()}
</ModalDialog.Body>
<ModalDialog.Footer className="p-4">
<ActionRow>
<ModalDialog.CloseButton variant="tertiary">
{formatMessage(messages.cancelLabel)}
</ModalDialog.CloseButton>
<StatefulButton
labels={{
default: formatMessage(messages.saveLabel),
pending: formatMessage(messages.pendingSaveLabel),
}}
description="Form save button"
data-testid="submissionButton"
disabled={submitButtonState === RequestStatus.IN_PROGRESS}
state={submitButtonState}
type="submit"
/>
</ActionRow>
</ModalDialog.Footer>
</Form>
</ModalDialog>
);
};
ORASettings.propTypes = {
onClose: PropTypes.func.isRequired,
};
export default ORASettings;

View File

@@ -0,0 +1,155 @@
import {
render,
screen,
waitFor,
within,
} from '@testing-library/react';
import ReactDOM from 'react-dom';
import { Routes, Route, MemoryRouter } from 'react-router-dom';
import { initializeMockApp } from '@edx/frontend-platform';
import MockAdapter from 'axios-mock-adapter';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { AppProvider, PageWrap } from '@edx/frontend-platform/react';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import initializeStore from 'CourseAuthoring/store';
import { executeThunk } from 'CourseAuthoring/utils';
import PagesAndResourcesProvider from 'CourseAuthoring/pages-and-resources/PagesAndResourcesProvider';
import { getCourseAppsApiUrl, getCourseAdvancedSettingsApiUrl } from 'CourseAuthoring/pages-and-resources/data/api';
import { fetchCourseApps, fetchCourseAppSettings } from 'CourseAuthoring/pages-and-resources/data/thunks';
import ORASettings from './Settings';
import messages from './messages';
import {
courseId,
inititalState,
} from './factories/mockData';
let axiosMock;
let store;
const oraSettingsUrl = `/course/${courseId}/pages-and-resources/live/settings`;
// Modal creates a portal. Overriding ReactDOM.createPortal allows portals to be tested in jest.
ReactDOM.createPortal = jest.fn(node => node);
const renderComponent = () => (
render(
<IntlProvider locale="en">
<AppProvider store={store} wrapWithRouter={false}>
<PagesAndResourcesProvider courseId={courseId}>
<MemoryRouter initialEntries={[oraSettingsUrl]}>
<Routes>
<Route path={oraSettingsUrl} element={<PageWrap><ORASettings onClose={jest.fn()} /></PageWrap>} />
</Routes>
</MemoryRouter>
</PagesAndResourcesProvider>
</AppProvider>
</IntlProvider>,
)
);
const mockStore = async ({
apiStatus,
enabled,
}) => {
const settings = ['forceOnFlexiblePeerOpenassessments'];
const fetchCourseAppsUrl = `${getCourseAppsApiUrl()}/${courseId}`;
const fetchAdvancedSettingsUrl = `${getCourseAdvancedSettingsApiUrl()}/${courseId}`;
axiosMock.onGet(fetchCourseAppsUrl).reply(
200,
[{
allowed_operations: { enable: false, configure: true },
description: 'setting',
documentation_links: { learnMoreConfiguration: '' },
enabled,
id: 'ora_settings',
name: 'Flexible Peer Grading for ORAs',
}],
);
axiosMock.onGet(fetchAdvancedSettingsUrl).reply(
apiStatus,
{ force_on_flexible_peer_openassessments: { value: enabled } },
);
await executeThunk(fetchCourseApps(courseId), store.dispatch);
await executeThunk(fetchCourseAppSettings(courseId, settings), store.dispatch);
};
describe('ORASettings', () => {
beforeEach(async () => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: false,
roles: [],
},
});
store = initializeStore(inititalState);
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
});
it('Flexible peer grading configuration modal is visible', async () => {
renderComponent();
expect(screen.getByRole('dialog')).toBeVisible();
});
it('Displays "Configure Flexible Peer Grading" heading', async () => {
renderComponent();
const headingElement = screen.getByText(messages.heading.defaultMessage);
expect(headingElement).toBeVisible();
});
it('Displays loading component', () => {
renderComponent();
const loadingElement = screen.getByRole('status');
expect(within(loadingElement).getByText('Loading...')).toBeInTheDocument();
});
it('Displays Connection Error Alert', async () => {
await mockStore({ apiStatus: 404, enabled: true });
renderComponent();
const errorAlert = screen.getByRole('alert');
expect(within(errorAlert).getByText('We encountered a technical error when loading this page.', { exact: false })).toBeVisible();
});
it('Displays Permissions Error Alert', async () => {
await mockStore({ apiStatus: 403, enabled: true });
renderComponent();
const errorAlert = screen.getByRole('alert');
expect(within(errorAlert).getByText('You are not authorized to view this page', { exact: false })).toBeVisible();
});
it('Displays title, helper text and badge when flexible peer grading button is enabled', async () => {
await mockStore({ apiStatus: 200, enabled: true });
renderComponent();
const checkbox = screen.getByRole('checkbox', { name: /Flex Peer Grading/ });
expect(checkbox).toBeChecked();
await waitFor(() => {
const label = screen.getByText(messages.enableFlexPeerGradeLabel.defaultMessage);
const enableBadge = screen.getByTestId('enable-badge');
expect(label).toBeVisible();
expect(enableBadge).toHaveTextContent('Enabled');
});
});
it('Displays title, helper text and hides badge when flexible peer grading button is disabled', async () => {
renderComponent();
await mockStore({ apiStatus: 200, enabled: false });
const label = await screen.findByText(messages.enableFlexPeerGradeLabel.defaultMessage);
const enableBadge = screen.queryByTestId('enable-badge');
expect(label).toBeVisible();
expect(enableBadge).toBeNull();
});
});

View File

@@ -0,0 +1,32 @@
export const courseId = 'course-v1:org+num+run';
export const inititalState = {
courseDetail: {
courseId,
status: 'successful',
},
pagesAndResources: {
courseAppIds: ['ora_settings'],
loadingStatus: 'in-progress',
savingStatus: '',
courseAppsApiStatus: {},
courseAppSettings: {},
},
models: {
courseApps: {
ora_settings: {
id: 'ora_settings',
name: 'Flexible Peer Grading',
enabled: true,
description: 'Enable flexible peer grading',
allowedOperations: {
enable: false,
configure: true,
},
documentationLinks: {
learnMoreConfiguration: '',
},
},
},
},
};

View File

@@ -0,0 +1,54 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
heading: {
id: 'course-authoring.pages-resources.ora.heading',
defaultMessage: 'Configure Flexible Peer Grading',
description: 'Title for the modal dialog header',
},
ORASettingsHelpLink: {
id: 'course-authoring.pages-resources.ora.flex-peer-grading.link',
defaultMessage: 'Learn more about open response assessment settings',
description: 'Descriptive text for the hyperlink to the docs site',
},
enableFlexPeerGradeLabel: {
id: 'course-authoring.pages-resources.ora.flex-peer-grading.label',
defaultMessage: 'Flex Peer Grading',
description: 'Label for form switch',
},
enableFlexPeerGradeHelp: {
id: 'course-authoring.pages-resources.ora.flex-peer-grading.help',
defaultMessage: 'Turn on Flexible Peer Grading for all open response assessments in the course with peer grading.',
description: 'Help text describing what happens when the switch is enabled',
},
enabledBadgeLabel: {
id: 'course-authoring.pages-resources.ora.flex-peer-grading.enabled-badge.label',
defaultMessage: 'Enabled',
description: 'Label for badge that show users that a setting is enabled',
},
cancelLabel: {
id: 'course-authoring.pages-resources.ora.flex-peer-grading.cancel-button.label',
defaultMessage: 'Cancel',
description: 'Label for button that cancels user changes',
},
saveLabel: {
id: 'course-authoring.pages-resources.ora.flex-peer-grading.save-button.label',
defaultMessage: 'Save',
description: 'Label for button that saves user changes',
},
pendingSaveLabel: {
id: 'course-authoring.pages-resources.ora.flex-peer-grading.pending-save-button.label',
defaultMessage: 'Saving',
description: 'Label for button that has pending api save calls',
},
errorSavingTitle: {
id: 'course-authoring.pages-resources.ora.flex-peer-grading.save-error.title',
defaultMessage: 'We couldn\'t apply your changes.',
},
errorSavingMessage: {
id: 'course-authoring.pages-resources.ora.flex-peer-grading.save-error.message',
defaultMessage: 'Please check your entries and try again.',
},
});
export default messages;

View File

@@ -0,0 +1,20 @@
{
"name": "@openedx-plugins/course-app-ora_settings",
"version": "0.1.0",
"description": "Open Response Assessment configuration for courses using it",
"peerDependencies": {
"@edx/frontend-app-authoring": "*",
"@edx/frontend-platform": "*",
"@openedx/paragon": "*",
"prop-types": "*",
"react": "*",
"react-redux": "*",
"yup": "*"
},
"peerDependenciesMeta": {
"@edx/frontend-app-authoring": {
"optional": true
}
}
}

View File

@@ -8,40 +8,46 @@ import PropTypes from 'prop-types';
import { getConfig } from '@edx/frontend-platform';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/i18n';
import { useIntl, FormattedMessage } from '@edx/frontend-platform/i18n';
import {
ActionRow, Alert, Badge, Form, Hyperlink, ModalDialog, StatefulButton,
} from '@edx/paragon';
} from '@openedx/paragon';
import ExamsApiService from 'CourseAuthoring/data/services/ExamsApiService';
import StudioApiService from 'CourseAuthoring/data/services/StudioApiService';
import Loading from 'CourseAuthoring/generic/Loading';
import ConnectionErrorAlert from 'CourseAuthoring/generic/ConnectionErrorAlert';
import FormSwitchGroup from 'CourseAuthoring/generic/FormSwitchGroup';
import { useModel } from 'CourseAuthoring/generic/model-store';
import PermissionDeniedAlert from 'CourseAuthoring/generic/PermissionDeniedAlert';
import { useIsMobile } from 'CourseAuthoring/utils';
import { PagesAndResourcesContext } from 'CourseAuthoring/pages-and-resources/PagesAndResourcesProvider';
import { useCourseAuthoringContext } from 'CourseAuthoring/CourseAuthoringContext';
import StudioApiService from '../../data/services/StudioApiService';
import Loading from '../../generic/Loading';
import ConnectionErrorAlert from '../../generic/ConnectionErrorAlert';
import FormSwitchGroup from '../../generic/FormSwitchGroup';
import { useModel } from '../../generic/model-store';
import PermissionDeniedAlert from '../../generic/PermissionDeniedAlert';
import { useIsMobile } from '../../utils';
import { PagesAndResourcesContext } from '../PagesAndResourcesProvider';
import messages from './messages';
function ProctoringSettings({ intl, onClose }) {
const ProctoringSettings = ({ onClose }) => {
const intl = useIntl();
const initialFormValues = {
enableProctoredExams: false,
proctoringProvider: false,
proctortrackEscalationEmail: '',
escalationEmail: '',
allowOptingOut: false,
createZendeskTickets: false,
};
const [formValues, setFormValues] = useState(initialFormValues);
const [loading, setLoading] = useState(true);
const [loaded, setLoaded] = useState(false);
const [loadingConnectionError, setLoadingConnectionError] = useState(false);
const [loadingPermissionError, setLoadingPermissionError] = useState(false);
const [allowLtiProviders, setAllowLtiProviders] = useState(false);
const [availableProctoringProviders, setAvailableProctoringProviders] = useState([]);
const [requiresEscalationEmailProviders, setRequiresEscalationEmailProviders] = useState([]);
const [ltiProctoringProviders, setLtiProctoringProviders] = useState([]);
const [courseStartDate, setCourseStartDate] = useState('');
const [saveSuccess, setSaveSuccess] = useState(false);
const [saveError, setSaveError] = useState(false);
const [submissionInProgress, setSubmissionInProgress] = useState(false);
const [showProctortrackEscalationEmail, setShowProctortrackEscalationEmail] = useState(false);
const [showEscalationEmail, setShowEscalationEmail] = useState(false);
const isEdxStaff = getAuthenticatedUser().administrator;
const [formStatus, setFormStatus] = useState({
isValid: true,
@@ -50,90 +56,122 @@ function ProctoringSettings({ intl, onClose }) {
const isMobile = useIsMobile();
const modalVariant = isMobile ? 'dark' : 'default';
const isLtiProvider = (provider) => (
ltiProctoringProviders.some(p => p.name === provider)
);
function getProviderDisplayLabel(provider) {
// if a display label exists for this provider return it
return ltiProctoringProviders.find(p => p.name === provider)?.verbose_name || provider;
}
const { courseId } = useContext(PagesAndResourcesContext);
const { courseDetails } = useCourseAuthoringContext();
const org = courseDetails?.org;
const appInfo = useModel('courseApps', 'proctoring');
const alertRef = React.createRef();
const saveStatusAlertRef = React.createRef();
const proctoringEscalationEmailInputRef = useRef(null);
const submitButtonState = submissionInProgress ? 'pending' : 'default';
function handleChange(event) {
const handleChange = (event) => {
const { target } = event;
const value = target.type === 'checkbox' ? target.checked : target.value;
const { name } = target;
if (['allowOptingOut', 'createZendeskTickets'].includes(name)) {
if (['allowOptingOut'].includes(name)) {
// Form.Radio expects string values, so convert back to a boolean here
setFormValues({ ...formValues, [name]: value === 'true' });
} else if (name === 'proctoringProvider') {
const newFormValues = { ...formValues, proctoringProvider: value };
if (value === 'proctortrack') {
setFormValues({ ...newFormValues, createZendeskTickets: false });
setShowProctortrackEscalationEmail(true);
if (requiresEscalationEmailProviders.includes(value)) {
setFormValues({ ...newFormValues });
setShowEscalationEmail(true);
} else if (isLtiProvider(value)) {
setFormValues(newFormValues);
setShowEscalationEmail(true);
} else {
if (value === 'software_secure') {
setFormValues({ ...newFormValues, createZendeskTickets: true });
} else {
setFormValues(newFormValues);
}
setShowProctortrackEscalationEmail(false);
setFormValues(newFormValues);
setShowEscalationEmail(false);
}
} else {
setFormValues({ ...formValues, [name]: value });
}
}
};
function setFocusToProctortrackEscalationEmailInput() {
const setFocusToEscalationEmailInput = () => {
if (proctoringEscalationEmailInputRef && proctoringEscalationEmailInputRef.current) {
proctoringEscalationEmailInputRef.current.focus();
}
}
};
function postSettingsBackToServer() {
const dataToPostBack = {
const selectedProvider = formValues.proctoringProvider;
const isLtiProviderSelected = isLtiProvider(selectedProvider);
const studioDataToPostBack = {
proctored_exam_settings: {
enable_proctored_exams: formValues.enableProctoredExams,
proctoring_provider: formValues.proctoringProvider,
create_zendesk_tickets: formValues.createZendeskTickets,
// lti providers are managed outside edx-platform, lti_external indicates this
proctoring_provider: isLtiProviderSelected ? 'lti_external' : selectedProvider,
},
};
if (isEdxStaff) {
dataToPostBack.proctored_exam_settings.allow_proctoring_opt_out = formValues.allowOptingOut;
studioDataToPostBack.proctored_exam_settings.allow_proctoring_opt_out = formValues.allowOptingOut;
}
if (formValues.proctoringProvider === 'proctortrack') {
dataToPostBack.proctored_exam_settings.proctoring_escalation_email = formValues.proctortrackEscalationEmail === '' ? null : formValues.proctortrackEscalationEmail;
if (requiresEscalationEmailProviders.includes(formValues.proctoringProvider)) {
studioDataToPostBack.proctored_exam_settings.proctoring_escalation_email = formValues.escalationEmail === '' ? null : formValues.escalationEmail;
}
// only save back to exam service if necessary
setSubmissionInProgress(true);
StudioApiService.saveProctoredExamSettingsData(courseId, dataToPostBack).then(() => {
setSaveSuccess(true);
setSaveError(false);
setSubmissionInProgress(false);
}).catch(() => {
setSaveSuccess(false);
setSaveError(true);
setSubmissionInProgress(false);
});
const saveOperations = [StudioApiService.saveProctoredExamSettingsData(courseId, studioDataToPostBack)];
if (allowLtiProviders && ExamsApiService.isAvailable()) {
const selectedEscalationEmail = formValues.escalationEmail;
saveOperations.push(
ExamsApiService.saveCourseExamConfiguration(
courseId,
{
provider: isLtiProviderSelected ? formValues.proctoringProvider : null,
escalationEmail: (isLtiProviderSelected && selectedEscalationEmail !== '') ? selectedEscalationEmail : null,
},
),
);
}
Promise.all(saveOperations)
.then(() => {
setSaveSuccess(true);
setSaveError(false);
setSubmissionInProgress(false);
}).catch((error) => {
setSaveSuccess(false);
setSaveError(error);
setSubmissionInProgress(false);
});
}
function handleSubmit(event) {
const handleSubmit = (event) => {
event.preventDefault();
const isLtiProviderSelected = isLtiProvider(formValues.proctoringProvider);
if (
formValues.proctoringProvider === 'proctortrack'
&& !EmailValidator.validate(formValues.proctortrackEscalationEmail)
&& !(formValues.proctortrackEscalationEmail === '' && !formValues.enableProctoredExams)
(requiresEscalationEmailProviders.includes(formValues.proctoringProvider) || isLtiProviderSelected)
&& !EmailValidator.validate(formValues.escalationEmail)
&& !(formValues.escalationEmail === '' && !formValues.enableProctoredExams)
) {
if (formValues.proctortrackEscalationEmail === '') {
const errorMessage = intl.formatMessage(messages['authoring.proctoring.escalationemail.error.blank']);
if (formValues.escalationEmail === '') {
const errorMessage = intl.formatMessage(messages['authoring.proctoring.escalationemail.error.blank'], { proctoringProviderName: getProviderDisplayLabel(formValues.proctoringProvider) });
setFormStatus({
isValid: false,
errors: {
formProctortrackEscalationEmail: {
dialogErrorMessage: (<Alert.Link onClick={setFocusToProctortrackEscalationEmailInput} href="#formProctortrackEscalationEmail" data-testid="proctorTrackEscalationEmailErrorLink">{errorMessage}</Alert.Link>),
formEscalationEmail: {
dialogErrorMessage: (
<Alert.Link onClick={setFocusToEscalationEmailInput} href="#formEscalationEmail" data-testid="escalationEmailErrorLink">
{errorMessage}
</Alert.Link>
),
inputErrorMessage: errorMessage,
},
},
@@ -144,8 +182,8 @@ function ProctoringSettings({ intl, onClose }) {
setFormStatus({
isValid: false,
errors: {
formProctortrackEscalationEmail: {
dialogErrorMessage: (<Alert.Link onClick={setFocusToProctortrackEscalationEmailInput} href="#formProctortrackEscalationEmail" data-testid="proctorTrackEscalationEmailErrorLink">{errorMessage}</Alert.Link>),
formEscalationEmail: {
dialogErrorMessage: (<Alert.Link onClick={setFocusToEscalationEmailInput} href="#formEscalationEmail" data-testid="escalationEmailErrorLink">{errorMessage}</Alert.Link>),
inputErrorMessage: errorMessage,
},
},
@@ -154,13 +192,13 @@ function ProctoringSettings({ intl, onClose }) {
} else {
postSettingsBackToServer();
const errors = { ...formStatus.errors };
delete errors.formProctortrackEscalationEmail;
delete errors.formEscalationEmail;
setFormStatus({
isValid: true,
errors,
});
}
}
};
function cannotEditProctoringProvider() {
const currentDate = moment(moment()).format('YYYY-MM-DD[T]hh:mm:ss[Z]');
@@ -186,7 +224,7 @@ function ProctoringSettings({ intl, onClose }) {
disabled={isDisabledOption(provider)}
data-testid={provider}
>
{provider}
{getProviderDisplayLabel(provider)}
</option>
));
}
@@ -206,7 +244,7 @@ function ProctoringSettings({ intl, onClose }) {
);
}
const learnMoreLink = appInfo.documentationLinks?.learnMoreConfiguration && (
const learnMoreLink = appInfo?.documentationLinks?.learnMoreConfiguration && (
<Hyperlink
className="text-primary-500"
destination={appInfo.documentationLinks.learnMoreConfiguration}
@@ -218,16 +256,18 @@ function ProctoringSettings({ intl, onClose }) {
);
function renderContent() {
const isLtiProviderSelected = isLtiProvider(formValues.proctoringProvider);
return (
<>
{!formStatus.isValid && formStatus.errors.formProctortrackEscalationEmail
{!formStatus.isValid && formStatus.errors.formEscalationEmail
&& (
// tabIndex="-1" to make non-focusable element focusable
<Alert
id="proctortrackEscalationEmailError"
id="escalationEmailError"
variant="danger"
tabIndex="-1"
data-testid="proctortrackEscalationEmailError"
data-testid="escalationEmailError"
ref={alertRef}
>
{getFormErrorMessage()}
@@ -290,30 +330,30 @@ function ProctoringSettings({ intl, onClose }) {
</>
)}
{/* PROCTORTRACK ESCALATION EMAIL */}
{showProctortrackEscalationEmail && formValues.enableProctoredExams && (
<Form.Group controlId="formProctortrackEscalationEmail">
{/* ESCALATION EMAIL */}
{showEscalationEmail && formValues.enableProctoredExams && (
<Form.Group controlId="formEscalationEmail">
<Form.Label className="font-weight-bold">
{intl.formatMessage(messages['authoring.proctoring.escalationemail.label'])}
</Form.Label>
<Form.Control
ref={proctoringEscalationEmailInputRef}
type="email"
name="proctortrackEscalationEmail"
name="escalationEmail"
data-testid="escalationEmail"
onChange={handleChange}
value={formValues.proctortrackEscalationEmail}
isInvalid={Object.prototype.hasOwnProperty.call(formStatus.errors, 'formProctortrackEscalationEmail')}
aria-describedby="proctortrackEscalationEmailHelpText"
value={formValues.escalationEmail}
isInvalid={Object.prototype.hasOwnProperty.call(formStatus.errors, 'formEscalationEmail')}
aria-describedby="escalationEmailHelpText"
/>
<Form.Text id="proctortrackEscalationEmailHelpText">
<Form.Text id="escalationEmailHelpText">
{intl.formatMessage(messages['authoring.proctoring.escalationemail.help'])}
</Form.Text>
{Object.prototype.hasOwnProperty.call(formStatus.errors, 'formProctortrackEscalationEmail') && (
{Object.prototype.hasOwnProperty.call(formStatus.errors, 'formEscalationEmail') && (
<Form.Control.Feedback type="invalid">
{
formStatus.errors.formProctortrackEscalationEmail
&& formStatus.errors.formProctortrackEscalationEmail.inputErrorMessage
formStatus.errors.formEscalationEmail
&& formStatus.errors.formEscalationEmail.inputErrorMessage
}
</Form.Control.Feedback>
)}
@@ -321,7 +361,7 @@ function ProctoringSettings({ intl, onClose }) {
)}
{/* ALLOW OPTING OUT OF PROCTORED EXAMS */}
{ isEdxStaff && formValues.enableProctoredExams && (
{ isEdxStaff && formValues.enableProctoredExams && !isLtiProviderSelected && (
<fieldset aria-describedby="allowOptingOutHelpText">
<Form.Group controlId="formAllowingOptingOut">
<Form.Label as="legend" className="font-weight-bold">
@@ -329,6 +369,7 @@ function ProctoringSettings({ intl, onClose }) {
</Form.Label>
<Form.RadioSet
name="allowOptingOut"
data-testid="allowOptingOutRadio"
value={formValues.allowOptingOut.toString()}
onChange={handleChange}
>
@@ -342,29 +383,6 @@ function ProctoringSettings({ intl, onClose }) {
</Form.Group>
</fieldset>
)}
{/* CREATE ZENDESK TICKETS */}
{ isEdxStaff && formValues.enableProctoredExams && (
<fieldset aria-describedby="createZendeskTicketsText">
<Form.Group controlId="formCreateZendeskTickets">
<Form.Label as="legend" className="font-weight-bold">
{intl.formatMessage(messages['authoring.proctoring.createzendesk.label'])}
</Form.Label>
<Form.RadioSet
name="createZendeskTickets"
value={formValues.createZendeskTickets.toString()}
onChange={handleChange}
>
<Form.Radio value="true" data-testid="createZendeskTicketsYes">
{intl.formatMessage(messages['authoring.proctoring.yes'])}
</Form.Radio>
<Form.Radio value="false" data-testid="createZendeskTicketsNo">
{intl.formatMessage(messages['authoring.proctoring.no'])}
</Form.Radio>
</Form.RadioSet>
</Form.Group>
</fieldset>
)}
</>
);
}
@@ -416,21 +434,32 @@ function ProctoringSettings({ intl, onClose }) {
}
function renderSaveError() {
return (
<Alert
variant="danger"
data-testid="saveError"
tabIndex="-1"
ref={saveStatusAlertRef}
onClose={() => setSaveError(false)}
dismissible
>
let errorMessage = (
<FormattedMessage
id="authoring.proctoring.alert.error"
defaultMessage={`
We encountered a technical error while trying to save proctored exam settings.
This might be a temporary issue, so please try again in a few minutes.
If the problem persists, please go to the {support_link} for help.
`}
values={{
support_link: (
<Alert.Link href={getConfig().SUPPORT_URL}>
{intl.formatMessage(messages['authoring.proctoring.support.text'])}
</Alert.Link>
),
}}
/>
);
if (saveError?.response.status === 403) {
errorMessage = (
<FormattedMessage
id="authoring.examsettings.alert.error"
id="authoring.proctoring.alert.error.forbidden"
defaultMessage={`
We encountered a technical error while trying to save proctored exam settings.
This might be a temporary issue, so please try again in a few minutes.
If the problem persists, please go to the {support_link} for help.
You do not have permission to edit proctored exam settings for this course.
If you are a course team member and this problem persists,
please go to the {support_link} for help.
`}
values={{
support_link: (
@@ -440,51 +469,101 @@ function ProctoringSettings({ intl, onClose }) {
),
}}
/>
);
}
return (
<Alert
variant="danger"
data-testid="saveError"
tabIndex="-1"
ref={saveStatusAlertRef}
onClose={() => setSaveError(false)}
dismissible
>
{errorMessage}
</Alert>
);
}
useEffect(
() => {
StudioApiService.getProctoredExamSettingsData(courseId)
.then(
response => {
const proctoredExamSettings = response.data.proctored_exam_settings;
setLoaded(true);
setLoading(false);
setSubmissionInProgress(false);
setCourseStartDate(response.data.course_start_date);
const isProctortrack = proctoredExamSettings.proctoring_provider === 'proctortrack';
setShowProctortrackEscalationEmail(isProctortrack);
setAvailableProctoringProviders(response.data.available_proctoring_providers);
const proctoringEscalationEmail = proctoredExamSettings.proctoring_escalation_email;
useEffect(() => {
Promise.all([
StudioApiService.getProctoredExamSettingsData(courseId),
ExamsApiService.isAvailable() ? ExamsApiService.getCourseExamConfiguration(courseId) : Promise.resolve(),
ExamsApiService.isAvailable() ? ExamsApiService.getAvailableProviders(org) : Promise.resolve(),
])
.then(
([settingsResponse, examConfigResponse, ltiProvidersResponse]) => {
const proctoredExamSettings = settingsResponse.data.proctored_exam_settings;
setLoaded(true);
setLoading(false);
setSubmissionInProgress(false);
setCourseStartDate(settingsResponse.data.course_start_date);
setAvailableProctoringProviders(settingsResponse.data.available_proctoring_providers);
setRequiresEscalationEmailProviders(settingsResponse.data.requires_escalation_email_providers);
setFormValues({
...formValues,
enableProctoredExams: proctoredExamSettings.enable_proctored_exams,
proctoringProvider: proctoredExamSettings.proctoring_provider,
allowOptingOut: proctoredExamSettings.allow_proctoring_opt_out,
createZendeskTickets: proctoredExamSettings.create_zendesk_tickets,
// The backend API may return null for the proctoringEscalationEmail value, which is the default.
// In order to keep our email input component controlled, we use the empty string as the default
// and perform this conversion during GETs and POSTs.
proctortrackEscalationEmail: proctoringEscalationEmail === null ? '' : proctoringEscalationEmail,
});
},
).catch(
error => {
if (error.response.status === 403) {
setLoadingPermissionError(true);
} else {
setLoadingConnectionError(true);
}
setLoading(false);
setLoaded(false);
setSubmissionInProgress(false);
},
);
}, [],
);
// The list of providers returned by studio settings are the default behavior. If lti_external
// is available as an option display the list of LTI providers returned by the exam service.
// Setting 'lti_external' in studio indicates an LTI provider configured outside of edx-platform.
// This option is not directly selectable.
const proctoringProvidersStudio = settingsResponse.data.available_proctoring_providers;
const proctoringProvidersLti = ltiProvidersResponse?.data || [];
const enableLtiProviders = proctoringProvidersStudio.includes('lti_external');
setAllowLtiProviders(enableLtiProviders);
setLtiProctoringProviders(proctoringProvidersLti);
// flatten provider objects and coalesce values to just the provider key
let availableProviders = proctoringProvidersStudio.filter(value => value !== 'lti_external');
if (enableLtiProviders) {
availableProviders = proctoringProvidersLti.reduce(
(result, provider) => [...result, provider.name],
availableProviders,
);
}
setAvailableProctoringProviders(availableProviders);
let selectedProvider;
if (proctoredExamSettings.proctoring_provider === 'lti_external') {
selectedProvider = examConfigResponse.data.provider;
} else {
selectedProvider = proctoredExamSettings.proctoring_provider;
}
const requiresEscalationEmailProvidersList = settingsResponse.data.requires_escalation_email_providers;
const isEscalationEmailRequired = requiresEscalationEmailProvidersList.includes(selectedProvider);
const ltiProviderSelected = proctoringProvidersLti.some(p => p.name === selectedProvider);
if (isEscalationEmailRequired || ltiProviderSelected) {
setShowEscalationEmail(true);
}
const proctoringEscalationEmail = ltiProviderSelected
? examConfigResponse.data.escalation_email
: proctoredExamSettings.proctoring_escalation_email;
setFormValues({
...formValues,
proctoringProvider: selectedProvider,
enableProctoredExams: proctoredExamSettings.enable_proctored_exams,
allowOptingOut: proctoredExamSettings.allow_proctoring_opt_out,
// The backend API may return null for the proctoringEscalationEmail value, which is the default.
// In order to keep our email input component controlled, we use the empty string as the default
// and perform this conversion during GETs and POSTs.
escalationEmail: proctoringEscalationEmail === null ? '' : proctoringEscalationEmail,
});
},
).catch(
error => {
if (error.response?.status === 403) {
setLoadingPermissionError(true);
} else {
setLoadingConnectionError(true);
}
setLoading(false);
setLoaded(false);
setSubmissionInProgress(false);
},
);
}, []);
useEffect(() => {
if ((saveSuccess || saveError) && !!saveStatusAlertRef.current) {
@@ -545,13 +624,12 @@ function ProctoringSettings({ intl, onClose }) {
</Form>
</ModalDialog>
);
}
};
ProctoringSettings.propTypes = {
intl: intlShape.isRequired,
onClose: PropTypes.func.isRequired,
};
ProctoringSettings.defaultProps = {};
export default injectIntl(ProctoringSettings);
export default ProctoringSettings;

View File

@@ -0,0 +1,844 @@
import {
render, screen, cleanup, waitFor, fireEvent, act,
initializeMocks,
} from 'CourseAuthoring/testUtils';
import { mergeConfig } from '@edx/frontend-platform';
import StudioApiService from 'CourseAuthoring/data/services/StudioApiService';
import ExamsApiService from 'CourseAuthoring/data/services/ExamsApiService';
import PagesAndResourcesProvider from 'CourseAuthoring/pages-and-resources/PagesAndResourcesProvider';
import { CourseAuthoringProvider } from 'CourseAuthoring/CourseAuthoringContext';
import { getCourseDetailsUrl } from 'CourseAuthoring/data/api';
import ProctoredExamSettings from './Settings';
const courseId = 'course-v1%3AedX%2BDemoX%2BDemo_Course';
const defaultProps = {
courseId,
onClose: () => {},
};
const renderComponent = children => (
<CourseAuthoringProvider courseId={defaultProps.courseId}>
<PagesAndResourcesProvider courseId={defaultProps.courseId}>
{children}
</PagesAndResourcesProvider>
</CourseAuthoringProvider>
);
let axiosMock;
describe('ProctoredExamSettings', () => {
/**
* @param {boolean} isAdmin
* @param {string | undefined} org
*/
function setupApp(isAdmin = true, org = undefined) {
mergeConfig({
EXAMS_BASE_URL: 'http://exams.testing.co',
}, 'CourseAuthoringConfig');
const user = {
userId: 3,
username: 'abc123',
administrator: isAdmin,
roles: [],
};
const mocks = initializeMocks({
user,
initialState: {
models: {
courseApps: {
proctoring: {},
},
},
},
});
axiosMock = mocks.axiosMock;
axiosMock
.onGet(getCourseDetailsUrl(courseId, user.username))
.reply(200, {
courseId,
name: 'Course Test',
start: Date(),
...(org ? { org } : {}),
});
axiosMock.onGet(`${ExamsApiService.getExamsBaseUrl()}/api/v1/providers`)
.reply(200, [{ name: 'test_lti', verbose_name: 'LTI Provider' }]);
if (org) {
axiosMock.onGet(`${ExamsApiService.getExamsBaseUrl()}/api/v1/providers?org=${org}`)
.reply(200, [{ name: 'test_lti', verbose_name: 'LTI Provider' }]);
}
axiosMock.onGet(
`${ExamsApiService.getExamsBaseUrl()}/api/v1/configs/course_id/${defaultProps.courseId}`,
).reply(200, {
provider: null,
});
axiosMock.onGet(
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
).reply(200, {
proctored_exam_settings: {
enable_proctored_exams: true,
allow_proctoring_opt_out: false,
proctoring_provider: 'mockproc',
proctoring_escalation_email: 'test@example.com',
},
available_proctoring_providers: ['software_secure', 'mockproc', 'lti_external'],
requires_escalation_email_providers: ['test_lti'],
course_start_date: '2070-01-01T00:00:00Z',
});
}
beforeEach(async () => {
setupApp();
});
describe('Field dependencies', () => {
beforeEach(async () => {
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
});
it('Hides all other fields when enabledProctorExam is false when first loaded', async () => {
cleanup();
// Overrides the handler defined in beforeEach.
axiosMock.onGet(
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
).reply(200, {
proctored_exam_settings: {
enable_proctored_exams: false,
allow_proctoring_opt_out: false,
proctoring_provider: 'mockproc',
proctoring_escalation_email: 'test@example.com',
},
available_proctoring_providers: ['software_secure', 'mockproc'],
requires_escalation_email_providers: [],
course_start_date: '2070-01-01T00:00:00Z',
});
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
await waitFor(() => {
screen.getByText('Proctored exams');
});
const enabledProctoredExamCheck = screen.getByLabelText('Proctored exams');
expect(enabledProctoredExamCheck.checked).toEqual(false);
expect(screen.queryByText('Allow Opting Out of Proctored Exams')).toBeNull();
expect(screen.queryByDisplayValue('mockproc')).toBeNull();
expect(screen.queryByTestId('escalationEmail')).toBeNull();
});
it('Hides all other fields when enableProctoredExams toggled to false', async () => {
await waitFor(() => {
screen.getByText('Proctored exams');
});
expect(screen.queryByText('Allow opting out of proctored exams')).toBeDefined();
expect(screen.queryByDisplayValue('mockproc')).toBeDefined();
expect(screen.queryByTestId('escalationEmail')).toBeDefined();
let enabledProctoredExamCheck = screen.getAllByLabelText('Proctored exams', { exact: false })[0];
expect(enabledProctoredExamCheck.checked).toEqual(true);
fireEvent.click(enabledProctoredExamCheck, { target: { value: false } });
enabledProctoredExamCheck = screen.getByLabelText('Proctored exams');
expect(enabledProctoredExamCheck.checked).toEqual(false);
expect(screen.queryByText('Allow opting out of proctored exams')).toBeNull();
expect(screen.queryByDisplayValue('mockproc')).toBeNull();
expect(screen.queryByTestId('escalationEmail')).toBeNull();
});
it('Hides unsupported fields when lti provider is selected', async () => {
await waitFor(() => {
screen.getByDisplayValue('mockproc');
});
const selectElement = screen.getByDisplayValue('mockproc');
fireEvent.change(selectElement, { target: { value: 'test_lti' } });
expect(screen.queryByTestId('allowOptingOutRadio')).toBeNull();
});
});
describe('Validation with invalid escalation email', () => {
const proctoringProvidersRequiringEscalationEmail = ['test_lti'];
beforeEach(async () => {
axiosMock.onGet(
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
).reply(200, {
proctored_exam_settings: {
enable_proctored_exams: true,
allow_proctoring_opt_out: false,
proctoring_provider: 'lti_external',
proctoring_escalation_email: 'test@example.com',
},
available_proctoring_providers: ['software_secure', 'mockproc', 'lti_external'],
requires_escalation_email_providers: ['test_lti'],
course_start_date: '2070-01-01T00:00:00Z',
});
axiosMock.onGet(
`${ExamsApiService.getExamsBaseUrl()}/api/v1/configs/course_id/${defaultProps.courseId}`,
).reply(200, {
provider: 'test_lti',
escalation_email: 'test@example.com',
});
axiosMock.onPatch(
ExamsApiService.getExamConfigurationUrl(defaultProps.courseId),
).reply(204, {});
axiosMock.onPost(
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
).reply(200, {});
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
});
proctoringProvidersRequiringEscalationEmail.forEach(provider => {
it(`Creates an alert when no proctoring escalation email is provided with ${provider} selected`, async () => {
await waitFor(() => {
screen.getByDisplayValue('LTI Provider');
});
const selectEscalationEmailElement = screen.getByDisplayValue('test@example.com');
fireEvent.change(selectEscalationEmailElement, { target: { value: '' } });
const selectButton = screen.getByTestId('submissionButton');
fireEvent.click(selectButton);
// verify alert content and focus management
const escalationEmailError = screen.getByTestId('escalationEmailError');
expect(escalationEmailError.textContent).not.toBeNull();
expect(document.activeElement).toEqual(escalationEmailError);
// verify alert link links to offending input
const errorLink = screen.getByTestId('escalationEmailErrorLink');
fireEvent.click(errorLink);
const escalationEmailInput = screen.getByTestId('escalationEmail');
expect(document.activeElement).toEqual(escalationEmailInput);
});
it(`Creates an alert when invalid proctoring escalation email is provided with ${provider} selected`, async () => {
await waitFor(() => {
screen.getByDisplayValue('LTI Provider');
});
const selectElement = screen.getByDisplayValue('LTI Provider');
fireEvent.change(selectElement, { target: { value: provider } });
const selectEscalationEmailElement = screen.getByDisplayValue('test@example.com');
fireEvent.change(selectEscalationEmailElement, { target: { value: 'foo.bar' } });
const proctoringForm = screen.getByTestId('proctoringForm');
fireEvent.submit(proctoringForm);
// verify alert content and focus management
const escalationEmailError = screen.getByTestId('escalationEmailError');
expect(document.activeElement).toEqual(escalationEmailError);
expect(escalationEmailError.textContent).not.toBeNull();
expect(document.activeElement).toEqual(escalationEmailError);
// verify alert link links to offending input
const errorLink = screen.getByTestId('escalationEmailErrorLink');
fireEvent.click(errorLink);
const escalationEmailInput = screen.getByTestId('escalationEmail');
expect(document.activeElement).toEqual(escalationEmailInput);
});
it('Creates an alert when invalid proctoring escalation email is provided with proctoring disabled', async () => {
await waitFor(() => {
screen.getByDisplayValue('LTI Provider');
});
const selectEscalationEmailElement = screen.getByDisplayValue('test@example.com');
fireEvent.change(selectEscalationEmailElement, { target: { value: 'foo.bar' } });
const enableProctoringElement = screen.getByText('Proctored exams');
fireEvent.click(enableProctoringElement);
const selectButton = screen.getByTestId('submissionButton');
fireEvent.click(selectButton);
// verify alert content and focus management
const escalationEmailError = screen.getByTestId('escalationEmailError');
expect(document.activeElement).toEqual(escalationEmailError);
expect(escalationEmailError.textContent).not.toBeNull();
expect(document.activeElement).toEqual(escalationEmailError);
});
it('Has no error when empty proctoring escalation email is provided with proctoring disabled', async () => {
await waitFor(() => {
screen.getByDisplayValue('LTI Provider');
});
const selectEscalationEmailElement = screen.getByDisplayValue('test@example.com');
fireEvent.change(selectEscalationEmailElement, { target: { value: '' } });
const enableProctoringElement = screen.getByText('Proctored exams');
fireEvent.click(enableProctoringElement);
const selectButton = screen.getByTestId('submissionButton');
fireEvent.click(selectButton);
// verify there is no escalation email alert, and focus has been set on save success alert
expect(screen.queryByTestId('escalationEmailError')).toBeNull();
await waitFor(() => {
const errorAlert = screen.getByTestId('saveSuccess');
expect(errorAlert.textContent).toEqual(
expect.stringContaining('Proctored exam settings saved successfully.'),
);
expect(document.activeElement).toEqual(errorAlert);
});
});
it(`Has no error when valid proctoring escalation email is provided with ${provider} selected`, async () => {
await waitFor(() => {
screen.getByDisplayValue('LTI Provider');
});
const selectEscalationEmailElement = screen.getByDisplayValue('test@example.com');
fireEvent.change(selectEscalationEmailElement, { target: { value: 'foo@bar.com' } });
const selectButton = screen.getByTestId('submissionButton');
fireEvent.click(selectButton);
// verify there is no escalation email alert, and focus has been set on save success alert
expect(screen.queryByTestId('escalationEmailError')).toBeNull();
await waitFor(() => {
const errorAlert = screen.getByTestId('saveSuccess');
expect(errorAlert.textContent).toEqual(
expect.stringContaining('Proctored exam settings saved successfully.'),
);
expect(document.activeElement).toEqual(errorAlert);
});
});
it(`Escalation email field hidden when proctoring backend is not ${provider}`, async () => {
await waitFor(() => {
screen.getByDisplayValue('LTI Provider');
});
const proctoringBackendSelect = screen.getByDisplayValue('LTI Provider');
const selectEscalationEmailElement = screen.getByTestId('escalationEmail');
expect(selectEscalationEmailElement.value).toEqual('test@example.com');
fireEvent.change(proctoringBackendSelect, { target: { value: 'software_secure' } });
expect(screen.queryByTestId('escalationEmail')).toBeNull();
});
it(`Escalation email Field Show when proctoring backend is switched back to ${provider}`, async () => {
await waitFor(() => {
screen.getByDisplayValue('LTI Provider');
});
const proctoringBackendSelect = screen.getByDisplayValue('LTI Provider');
let selectEscalationEmailElement = screen.getByTestId('escalationEmail');
fireEvent.change(proctoringBackendSelect, { target: { value: 'software_secure' } });
expect(screen.queryByTestId('escalationEmail')).toBeNull();
fireEvent.change(proctoringBackendSelect, { target: { value: provider } });
expect(screen.queryByTestId('escalationEmail')).toBeDefined();
selectEscalationEmailElement = screen.getByTestId('escalationEmail');
expect(selectEscalationEmailElement.value).toEqual('test@example.com');
});
it('Submits form when "Enter" key is hit in the escalation email field', async () => {
await waitFor(() => {
screen.getByDisplayValue('LTI Provider');
});
const selectEscalationEmailElement = screen.getByDisplayValue('test@example.com');
fireEvent.change(selectEscalationEmailElement, { target: { value: '' } });
fireEvent.submit(selectEscalationEmailElement);
// if the error appears, the form has been submitted
expect(screen.getByTestId('escalationEmailError')).toBeDefined();
});
});
});
describe('Proctoring provider options', () => {
const mockGetFutureCourseData = {
proctored_exam_settings: {
enable_proctored_exams: true,
allow_proctoring_opt_out: false,
proctoring_provider: 'mockproc',
proctoring_escalation_email: 'test@example.com',
},
available_proctoring_providers: ['software_secure', 'mockproc'],
requires_escalation_email_providers: [],
course_start_date: '2099-01-01T00:00:00Z',
};
const mockGetPastCourseData = {
proctored_exam_settings: {
enable_proctored_exams: true,
allow_proctoring_opt_out: false,
proctoring_provider: 'mockproc',
proctoring_escalation_email: 'test@example.com',
},
available_proctoring_providers: ['software_secure', 'mockproc'],
requires_escalation_email_providers: [],
course_start_date: '2013-01-01T00:00:00Z',
};
function mockCourseData(data) {
axiosMock.onGet(StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId)).reply(200, data);
}
it('Disables irrelevant proctoring provider fields when user is not an administrator and it is after start date', async () => {
const isAdmin = false;
setupApp(isAdmin);
mockCourseData(mockGetPastCourseData);
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
const providerOption = screen.getByTestId('software_secure');
expect(providerOption.hasAttribute('disabled')).toEqual(true);
});
it('Enables all proctoring provider options if user is not an administrator and it is before start date', async () => {
const isAdmin = false;
setupApp(isAdmin);
mockCourseData(mockGetFutureCourseData);
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
const providerOption = screen.getByTestId('software_secure');
expect(providerOption.hasAttribute('disabled')).toEqual(false);
});
it('Sends the org to the proctoring provider endpoint', async () => {
const isAdmin = false;
const org = 'test-org';
setupApp(isAdmin, org);
mockCourseData(mockGetFutureCourseData);
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
const providerOption = screen.getByTestId('software_secure');
expect(providerOption.hasAttribute('disabled')).toEqual(false);
});
it('Enables all proctoring provider options if user administrator and it is after start date', async () => {
const isAdmin = true;
setupApp(isAdmin);
mockCourseData(mockGetPastCourseData);
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
const providerOption = screen.getByTestId('software_secure');
expect(providerOption.hasAttribute('disabled')).toEqual(false);
});
it('Enables all proctoring provider options if user administrator and it is before start date', async () => {
const isAdmin = true;
setupApp(isAdmin);
mockCourseData(mockGetFutureCourseData);
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
const providerOption = screen.getByTestId('software_secure');
expect(providerOption.hasAttribute('disabled')).toEqual(false);
});
it('Does not include lti_external as a selectable option', async () => {
const courseData = {
...mockGetFutureCourseData,
available_proctoring_providers: ['lti_external', 'mockproc'],
};
mockCourseData(courseData);
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
await waitFor(() => {
screen.getByDisplayValue('mockproc');
});
expect(screen.queryByTestId('lti_external')).toBeNull();
});
it('Includes lti proctoring provider options when lti_external is allowed by studio', async () => {
const courseData = {
...mockGetFutureCourseData,
available_proctoring_providers: ['lti_external', 'mockproc'],
};
mockCourseData(courseData);
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
await waitFor(() => {
screen.getByDisplayValue('mockproc');
});
const providerOption = screen.getByTestId('test_lti');
// as as admin the provider should not be disabled
expect(providerOption.hasAttribute('disabled')).toEqual(false);
});
it('Does not include lti provider options when lti_external is not available in studio', async () => {
const isAdmin = true;
setupApp(isAdmin);
mockCourseData(mockGetFutureCourseData);
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
await waitFor(() => {
screen.getByDisplayValue('mockproc');
});
const providerOption = screen.queryByTestId('test_lti');
expect(providerOption).not.toBeInTheDocument();
});
it('Does not request lti provider options if there is no exam service url configuration', async () => {
mergeConfig({
EXAMS_BASE_URL: null,
}, 'CourseAuthoringConfig');
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
await waitFor(() => {
screen.getByDisplayValue('mockproc');
});
// (1) for studio settings
// (2) waffle flags
// (3) for course details
expect(axiosMock.history.get.length).toBe(3);
expect(axiosMock.history.get[0].url.includes('proctored_exam_settings')).toEqual(true);
});
it('Selected LTI proctoring provider is shown on page load', async () => {
const courseData = { ...mockGetFutureCourseData };
courseData.available_proctoring_providers = ['lti_external', 'mockproc'];
courseData.proctored_exam_settings.proctoring_provider = 'lti_external';
mockCourseData(courseData);
axiosMock.onGet(
`${ExamsApiService.getExamsBaseUrl()}/api/v1/configs/course_id/${defaultProps.courseId}`,
).reply(200, {
provider: 'test_lti',
});
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
await waitFor(() => {
screen.getByText('Proctoring provider');
});
// make sure test_lti is the selected provider
expect(screen.getByDisplayValue('LTI Provider')).toBeInTheDocument();
});
});
describe('Toggles field visibility based on user permissions', () => {
it('Hides opting out for non edX staff', async () => {
setupApp(false);
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
expect(screen.queryByTestId('allowOptingOutYes')).toBeNull();
});
it('Shows opting out for edX staff', async () => {
setupApp(true);
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
expect(screen.queryByTestId('allowOptingOutYes')).not.toBeNull();
});
});
describe('Connection states', () => {
it('Shows the spinner before the connection is complete', async () => {
render(renderComponent(<ProctoredExamSettings {...defaultProps} />));
const spinner = await screen.findByRole('status');
expect(spinner.textContent).toEqual('Loading...');
});
it('Show connection error message when we suffer studio server side error', async () => {
axiosMock.onGet(
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
).reply(500);
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
const connectionError = screen.getByTestId('connectionErrorAlert');
expect(connectionError.textContent).toEqual(
expect.stringContaining('We encountered a technical error when loading this page.'),
);
});
it('Show connection error message when we suffer edx-exams server side error', async () => {
axiosMock.onGet(
`${ExamsApiService.getExamsBaseUrl()}/api/v1/providers`,
).reply(500);
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
const connectionError = screen.getByTestId('connectionErrorAlert');
expect(connectionError.textContent).toEqual(
expect.stringContaining('We encountered a technical error when loading this page.'),
);
});
it('Show permission error message when user do not have enough permission', async () => {
axiosMock.onGet(
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
).reply(403);
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
const permissionError = screen.getByTestId('permissionDeniedAlert');
expect(permissionError.textContent).toEqual(
expect.stringContaining('You are not authorized to view this page'),
);
});
});
describe('Save settings', () => {
beforeEach(async () => {
axiosMock.onPost(
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
).reply(200, 'success');
axiosMock.onPatch(
`${ExamsApiService.getExamsBaseUrl()}/api/v1/configs/course_id/${defaultProps.courseId}`,
).reply(200, 'success');
});
it('Disable button while submitting', async () => {
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
let submitButton = screen.getByTestId('submissionButton');
expect(screen.queryByTestId('saveInProgress')).toBeFalsy();
fireEvent.click(submitButton);
submitButton = screen.getByTestId('submissionButton');
expect(submitButton).toHaveAttribute('disabled');
});
it('Makes API call successfully with proctoring_escalation_email if test_lti', async () => {
// Setup mock to include test_lti as available provider
axiosMock.onGet(
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
).reply(200, {
proctored_exam_settings: {
enable_proctored_exams: true,
allow_proctoring_opt_out: false,
proctoring_provider: 'mockproc',
proctoring_escalation_email: 'test@example.com',
},
available_proctoring_providers: ['software_secure', 'mockproc', 'lti_external'],
requires_escalation_email_providers: ['test_lti'],
course_start_date: '2070-01-01T00:00:00Z',
});
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
// Make a change to the provider to test_lti and set the email
const selectElement = screen.getByDisplayValue('mockproc');
fireEvent.change(selectElement, { target: { value: 'test_lti' } });
const escalationEmail = screen.getByTestId('escalationEmail');
expect(escalationEmail.value).toEqual('test@example.com');
fireEvent.change(escalationEmail, { target: { value: 'test_lti@example.com' } });
expect(escalationEmail.value).toEqual('test_lti@example.com');
const submitButton = screen.getByTestId('submissionButton');
fireEvent.click(submitButton);
expect(axiosMock.history.post.length).toBe(1);
expect(JSON.parse(axiosMock.history.post[0].data)).toEqual({
proctored_exam_settings: {
enable_proctored_exams: true,
allow_proctoring_opt_out: false,
proctoring_provider: 'lti_external',
proctoring_escalation_email: 'test_lti@example.com',
},
});
expect(axiosMock.history.patch.length).toBe(1);
expect(JSON.parse(axiosMock.history.patch[0].data)).toEqual({
provider: 'test_lti',
escalation_email: 'test_lti@example.com',
});
await waitFor(() => {
const errorAlert = screen.getByTestId('saveSuccess');
expect(errorAlert.textContent).toEqual(
expect.stringContaining('Proctored exam settings saved successfully.'),
);
expect(document.activeElement).toEqual(errorAlert);
});
});
it('Makes API call successfully without proctoring_escalation_email if not requiring escalation email', async () => {
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
// make sure we have not selected a provider requiring escalation email
expect(screen.getByDisplayValue('mockproc')).toBeDefined();
const submitButton = screen.getByTestId('submissionButton');
fireEvent.click(submitButton);
expect(axiosMock.history.post.length).toBe(1);
expect(JSON.parse(axiosMock.history.post[0].data)).toEqual({
proctored_exam_settings: {
enable_proctored_exams: true,
allow_proctoring_opt_out: false,
proctoring_provider: 'mockproc',
},
});
await waitFor(() => {
const errorAlert = screen.getByTestId('saveSuccess');
expect(errorAlert.textContent).toEqual(
expect.stringContaining('Proctored exam settings saved successfully.'),
);
expect(document.activeElement).toEqual(errorAlert);
});
});
it('Successfully updates exam configuration and studio provider is set to "lti_external" for lti providers', async () => {
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
// Make a change to the provider to test_lti and set the email
const selectElement = screen.getByDisplayValue('mockproc');
fireEvent.change(selectElement, { target: { value: 'test_lti' } });
const escalationEmail = screen.getByTestId('escalationEmail');
expect(escalationEmail.value).toEqual('test@example.com');
fireEvent.change(escalationEmail, { target: { value: 'test_lti@example.com' } });
expect(escalationEmail.value).toEqual('test_lti@example.com');
const submitButton = screen.getByTestId('submissionButton');
fireEvent.click(submitButton);
// update exam service config
expect(axiosMock.history.patch.length).toBe(1);
expect(JSON.parse(axiosMock.history.patch[0].data)).toEqual({
provider: 'test_lti',
escalation_email: 'test_lti@example.com',
});
// update studio settings
expect(axiosMock.history.post.length).toBe(1);
expect(JSON.parse(axiosMock.history.post[0].data)).toEqual({
proctored_exam_settings: {
enable_proctored_exams: true,
allow_proctoring_opt_out: false,
proctoring_provider: 'lti_external',
proctoring_escalation_email: 'test_lti@example.com',
},
});
await waitFor(() => {
const errorAlert = screen.getByTestId('saveSuccess');
expect(errorAlert.textContent).toEqual(
expect.stringContaining('Proctored exam settings saved successfully.'),
);
expect(document.activeElement).toEqual(errorAlert);
});
});
it('Sets exam service provider to null if a non-lti provider is selected', async () => {
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
const submitButton = screen.getByTestId('submissionButton');
fireEvent.click(submitButton);
// update exam service config
expect(axiosMock.history.patch.length).toBe(1);
expect(JSON.parse(axiosMock.history.patch[0].data)).toEqual({
provider: null,
escalation_email: null,
});
expect(axiosMock.history.patch.length).toBe(1);
expect(axiosMock.history.post.length).toBe(1);
expect(JSON.parse(axiosMock.history.post[0].data)).toEqual({
proctored_exam_settings: {
enable_proctored_exams: true,
allow_proctoring_opt_out: false,
proctoring_provider: 'mockproc',
},
});
await waitFor(() => {
const errorAlert = screen.getByTestId('saveSuccess');
expect(errorAlert.textContent).toEqual(
expect.stringContaining('Proctored exam settings saved successfully.'),
);
expect(document.activeElement).toEqual(errorAlert);
});
});
it('Does not update exam service if lti is not enabled in studio', async () => {
axiosMock.onGet(
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
).reply(200, {
proctored_exam_settings: {
enable_proctored_exams: true,
allow_proctoring_opt_out: false,
proctoring_provider: 'mockproc',
proctoring_escalation_email: 'test@example.com',
},
available_proctoring_providers: ['software_secure', 'mockproc'],
requires_escalation_email_providers: [],
course_start_date: '2070-01-01T00:00:00Z',
});
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
const submitButton = screen.getByTestId('submissionButton');
fireEvent.click(submitButton);
// does not update exam service config
expect(axiosMock.history.patch.length).toBe(0);
// does update studio
expect(axiosMock.history.post.length).toBe(1);
expect(JSON.parse(axiosMock.history.post[0].data)).toEqual({
proctored_exam_settings: {
enable_proctored_exams: true,
allow_proctoring_opt_out: false,
proctoring_provider: 'mockproc',
},
});
await waitFor(() => {
const errorAlert = screen.getByTestId('saveSuccess');
expect(errorAlert.textContent).toEqual(
expect.stringContaining('Proctored exam settings saved successfully.'),
);
expect(document.activeElement).toEqual(errorAlert);
});
});
it('Makes studio API call generated error', async () => {
axiosMock.onPost(
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
).reply(500);
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
const submitButton = screen.getByTestId('submissionButton');
fireEvent.click(submitButton);
expect(axiosMock.history.post.length).toBe(1);
await waitFor(() => {
const errorAlert = screen.getByTestId('saveError');
expect(errorAlert.textContent).toEqual(
expect.stringContaining('We encountered a technical error while trying to save proctored exam settings'),
);
expect(document.activeElement).toEqual(errorAlert);
});
});
it('Makes exams API call generated error', async () => {
axiosMock.onPatch(
`${ExamsApiService.getExamsBaseUrl()}/api/v1/configs/course_id/${defaultProps.courseId}`,
).reply(500, 'error');
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
const submitButton = screen.getByTestId('submissionButton');
fireEvent.click(submitButton);
expect(axiosMock.history.post.length).toBe(1);
await waitFor(() => {
const errorAlert = screen.getByTestId('saveError');
expect(errorAlert.textContent).toEqual(
expect.stringContaining('We encountered a technical error while trying to save proctored exam settings'),
);
expect(document.activeElement).toEqual(errorAlert);
});
});
test('Exams API permission error', async () => {
axiosMock.onPatch(
`${ExamsApiService.getExamsBaseUrl()}/api/v1/configs/course_id/${defaultProps.courseId}`,
).reply(403, 'error');
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
const submitButton = screen.getByTestId('submissionButton');
fireEvent.click(submitButton);
expect(axiosMock.history.post.length).toBe(1);
await waitFor(() => {
const errorAlert = screen.getByTestId('saveError');
expect(errorAlert.textContent).toEqual(
expect.stringContaining('You do not have permission to edit proctored exam settings for this course'),
);
expect(document.activeElement).toEqual(errorAlert);
});
});
it('Manages focus correctly after different save statuses', async () => {
// first make a call that will cause a save error
axiosMock.onPost(
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
).reply(500);
await act(async () => render(renderComponent(<ProctoredExamSettings {...defaultProps} />)));
const submitButton = screen.getByTestId('submissionButton');
fireEvent.click(submitButton);
expect(axiosMock.history.post.length).toBe(1);
await waitFor(() => {
const errorAlert = screen.getByTestId('saveError');
expect(errorAlert.textContent).toEqual(
expect.stringContaining('We encountered a technical error while trying to save proctored exam settings'),
);
expect(document.activeElement).toEqual(errorAlert);
});
// now make a call that will allow for a successful save
axiosMock.onPost(
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
).reply(200, 'success');
fireEvent.click(submitButton);
expect(axiosMock.history.post.length).toBe(2);
await waitFor(() => {
const successAlert = screen.getByTestId('saveSuccess');
expect(successAlert.textContent).toEqual(
expect.stringContaining('Proctored exam settings saved successfully.'),
);
expect(document.activeElement).toEqual(successAlert);
});
});
});
});

View File

@@ -1,6 +1,11 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
'authoring.proctoring.alert.forbidden': {
id: 'authoring.proctoring.alert.forbidden',
defaultMessage: 'You do not have permission to edit proctored exam settings for this course. If you are a course team member and this problem persists, please go to the {support_link} for help.',
description: 'Alert message for proctoring settings permission error.',
},
'authoring.proctoring.no': {
id: 'authoring.proctoring.no',
defaultMessage: 'No',
@@ -53,7 +58,7 @@ const messages = defineMessages({
},
'authoring.proctoring.escalationemail.label': {
id: 'authoring.proctoring.escalationemail.label',
defaultMessage: 'Proctortrack escalation email',
defaultMessage: 'Escalation email',
description: 'Label for escalation email text field',
},
'authoring.proctoring.escalationemail.help': {
@@ -63,12 +68,12 @@ const messages = defineMessages({
},
'authoring.proctoring.escalationemail.error.blank': {
id: 'authoring.proctoring.escalationemail.error.blank',
defaultMessage: 'The Proctortrack Escalation Email field cannot be empty if proctortrack is the selected provider.',
defaultMessage: 'The Escalation Email field cannot be empty if {proctoringProviderName} is the selected provider.',
description: 'Error message for missing required email field.',
},
'authoring.proctoring.escalationemail.error.invalid': {
id: 'authoring.proctoring.escalationemail.error.invalid',
defaultMessage: 'The Proctortrack Escalation Email field is in the wrong format and is not valid.',
defaultMessage: 'The Escalation Email field is in the wrong format and is not valid.',
description: 'Error message for a invalid email format.',
},
'authoring.proctoring.allowoptout.label': {
@@ -76,11 +81,6 @@ const messages = defineMessages({
defaultMessage: 'Allow learners to opt out of proctoring on proctored exams',
description: 'Label for radio selection allowing proctored exam opt out',
},
'authoring.proctoring.createzendesk.label': {
id: 'authoring.proctoring.createzendesk.label',
defaultMessage: 'Create Zendesk tickets for suspicious attempts',
description: 'Label for Zendesk ticket creation radio select.',
},
'authoring.proctoring.error.single': {
id: 'authoring.proctoring.error.single',
defaultMessage: 'There is 1 error in this form.',

View File

@@ -0,0 +1,20 @@
{
"name": "@openedx-plugins/course-app-proctoring",
"version": "0.1.0",
"description": "Proctoring configuration for courses using it",
"peerDependencies": {
"@edx/frontend-app-authoring": "*",
"@edx/frontend-platform": "*",
"@openedx/paragon": "*",
"classnames": "*",
"email-validator": "*",
"react": "*",
"prop-types": "*",
"moment": "*"
},
"peerDependenciesMeta": {
"@edx/frontend-app-authoring": {
"optional": true
}
}
}

View File

@@ -1,19 +1,20 @@
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import PropTypes from 'prop-types';
import React from 'react';
import * as Yup from 'yup';
import { getConfig } from '@edx/frontend-platform';
import FormSwitchGroup from '../../generic/FormSwitchGroup';
import { useAppSetting } from '../../utils';
import AppSettingsModal from '../app-settings-modal/AppSettingsModal';
import FormSwitchGroup from 'CourseAuthoring/generic/FormSwitchGroup';
import { useAppSetting } from 'CourseAuthoring/utils';
import AppSettingsModal from 'CourseAuthoring/pages-and-resources/app-settings-modal/AppSettingsModal';
import messages from './messages';
function ProgressSettings({ intl, onClose }) {
const ProgressSettings = ({ onClose }) => {
const intl = useIntl();
const [disableProgressGraph, saveSetting] = useAppSetting('disableProgressGraph');
const showProgressGraphSetting = getConfig().ENABLE_PROGRESS_GRAPH_SETTINGS.toLowerCase() === 'true';
const showProgressGraphSetting = getConfig().ENABLE_PROGRESS_GRAPH_SETTINGS.toString().toLowerCase() === 'true';
const handleSettingsSave = (values) => {
if (showProgressGraphSetting) { saveSetting(!values.enableProgressGraph); }
const handleSettingsSave = async (values) => {
if (showProgressGraphSetting) { await saveSetting(!values.enableProgressGraph); }
};
return (
@@ -31,25 +32,24 @@ function ProgressSettings({ intl, onClose }) {
{
({ handleChange, handleBlur, values }) => (
showProgressGraphSetting && (
<FormSwitchGroup
id="enable-progress-graph"
name="enableProgressGraph"
label={intl.formatMessage(messages.enableGraphLabel)}
helpText={intl.formatMessage(messages.enableGraphHelp)}
onChange={handleChange}
onBlur={handleBlur}
checked={values.enableProgressGraph}
/>
<FormSwitchGroup
id="enable-progress-graph"
name="enableProgressGraph"
label={intl.formatMessage(messages.enableGraphLabel)}
helpText={intl.formatMessage(messages.enableGraphHelp)}
onChange={handleChange}
onBlur={handleBlur}
checked={values.enableProgressGraph}
/>
)
)
}
</AppSettingsModal>
);
}
};
ProgressSettings.propTypes = {
intl: intlShape.isRequired,
onClose: PropTypes.func.isRequired,
};
export default injectIntl(ProgressSettings);
export default ProgressSettings;

View File

@@ -0,0 +1,18 @@
{
"name": "@openedx-plugins/course-app-progress",
"version": "0.1.0",
"description": "Progress configuration for courses using it",
"peerDependencies": {
"@edx/frontend-app-authoring": "*",
"@edx/frontend-platform": "*",
"@openedx/paragon": "*",
"prop-types": "*",
"react": "*",
"yup": "*"
},
"peerDependenciesMeta": {
"@edx/frontend-app-authoring": {
"optional": true
}
}
}

View File

@@ -1,12 +1,13 @@
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { Button, Form, TransitionReplace } from '@edx/paragon';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Button, Form, TransitionReplace } from '@openedx/paragon';
import PropTypes from 'prop-types';
import React, { useState } from 'react';
import { GroupTypes, TeamSizes } from '../../data/constants';
import { GroupTypes, TeamSizes } from 'CourseAuthoring/data/constants';
import CollapsableEditor from '../../generic/CollapsableEditor';
import FormikControl from '../../generic/FormikControl';
import CollapsableEditor from 'CourseAuthoring/generic/CollapsableEditor';
import FormikControl from 'CourseAuthoring/generic/FormikControl';
import messages from './messages';
import { isGroupTypeEnabled } from './utils';
// Maps a team type to its corresponding intl message
const TeamTypeNameMessage = {
@@ -14,6 +15,10 @@ const TeamTypeNameMessage = {
label: messages.groupTypeOpen,
description: messages.groupTypeOpenDescription,
},
[GroupTypes.OPEN_MANAGED]: {
label: messages.groupTypeOpenManaged,
description: messages.groupTypeOpenManagedDescription,
},
[GroupTypes.PUBLIC_MANAGED]: {
label: messages.groupTypePublicManaged,
description: messages.groupTypePublicManagedDescription,
@@ -24,9 +29,10 @@ const TeamTypeNameMessage = {
},
};
function GroupEditor({
intl, group, onDelete, onChange, onBlur, fieldNameCommonBase, errors,
}) {
const GroupEditor = ({
group, onDelete, onChange, onBlur, fieldNameCommonBase, errors,
}) => {
const intl = useIntl();
const [isDeleting, setDeleting] = useState(false);
const [isOpen, setOpen] = useState(group.id === null);
const initiateDeletion = () => setDeleting(true);
@@ -105,7 +111,7 @@ function GroupEditor({
onChange={onChange}
onBlur={onBlur}
>
{Object.values(GroupTypes).map(groupType => (
{Object.values(GroupTypes).map(groupType => isGroupTypeEnabled(groupType) && (
<Form.Radio
key={groupType}
value={groupType}
@@ -133,7 +139,7 @@ function GroupEditor({
)}
</TransitionReplace>
);
}
};
export const groupShape = PropTypes.shape({
id: PropTypes.string,
@@ -144,7 +150,6 @@ export const groupShape = PropTypes.shape({
});
GroupEditor.propTypes = {
intl: intlShape.isRequired,
fieldNameCommonBase: PropTypes.string.isRequired,
errors: PropTypes.shape({
name: PropTypes.string,
@@ -165,4 +170,4 @@ GroupEditor.defaultProps = {
},
};
export default injectIntl(GroupEditor);
export default GroupEditor;

View File

@@ -0,0 +1,102 @@
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import { useFormikContext } from 'formik';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import GroupEditor from './GroupEditor';
import messages from './messages';
jest.mock('formik', () => ({
...jest.requireActual('formik'),
useFormikContext: jest.fn(),
}));
describe('GroupEditor', () => {
const mockIntl = { formatMessage: jest.fn() };
const mockGroup = {
id: '1',
name: 'Test Group',
description: 'Test Group Description',
type: 'open',
maxTeamSize: 5,
};
const mockProps = {
intl: mockIntl,
fieldNameCommonBase: 'test',
group: mockGroup,
onDelete: jest.fn(),
onChange: jest.fn(),
onBlur: jest.fn(),
errors: {},
};
const renderComponent = (overrideProps = {}) => render(
<IntlProvider locale="en" messages={{}}>
<GroupEditor {...mockProps} {...overrideProps} />
</IntlProvider>,
);
beforeEach(() => {
useFormikContext.mockReturnValue({
touched: {},
errors: {},
handleChange: jest.fn(),
handleBlur: jest.fn(),
setFieldError: jest.fn(),
});
jest.clearAllMocks();
});
test('renders without errors', () => {
renderComponent();
});
test('renders the group name and description', () => {
const { getByText } = renderComponent();
expect(getByText('Test Group')).toBeInTheDocument();
expect(getByText('Test Group Description')).toBeInTheDocument();
});
describe('group types messages', () => {
test('group type open message', () => {
const { getByLabelText, getByText } = renderComponent();
const expandButton = getByLabelText('Expand group editor');
expect(expandButton).toBeInTheDocument();
fireEvent.click(expandButton);
expect(getByText(messages.groupTypeOpenDescription.defaultMessage)).toBeInTheDocument();
});
test('group type public_managed message', () => {
const publicManagedGroupMock = {
id: '2',
name: 'Test Group',
description: 'Test Group Description',
type: 'public_managed',
maxTeamSize: 5,
};
const { getByLabelText, getByText } = renderComponent({ group: publicManagedGroupMock });
const expandButton = getByLabelText('Expand group editor');
expect(expandButton).toBeInTheDocument();
fireEvent.click(expandButton);
expect(getByText(messages.groupTypePublicManagedDescription.defaultMessage)).toBeInTheDocument();
});
test('group type private_managed message', () => {
const privateManagedGroupMock = {
id: '3',
name: 'Test Group',
description: 'Test Group Description',
type: 'private_managed',
maxTeamSize: 5,
};
const { getByLabelText, getByText } = renderComponent({ group: privateManagedGroupMock });
const expandButton = getByLabelText('Expand group editor');
expect(expandButton).toBeInTheDocument();
fireEvent.click(expandButton);
expect(getByText(messages.groupTypePrivateManagedDescription.defaultMessage)).toBeInTheDocument();
});
});
});

View File

@@ -1,31 +1,32 @@
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { Button, Form } from '@edx/paragon';
import { Add } from '@edx/paragon/icons';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Button, Form } from '@openedx/paragon';
import { Add } from '@openedx/paragon/icons';
import { FieldArray } from 'formik';
import PropTypes from 'prop-types';
import React from 'react';
import { v4 as uuid } from 'uuid';
import * as Yup from 'yup';
import { GroupTypes, TeamSizes } from '../../data/constants';
import FormikControl from '../../generic/FormikControl';
import { setupYupExtensions, useAppSetting } from '../../utils';
import AppSettingsModal from '../app-settings-modal/AppSettingsModal';
import { GroupTypes, TeamSizes } from 'CourseAuthoring/data/constants';
import FormikControl from 'CourseAuthoring/generic/FormikControl';
import { setupYupExtensions, useAppSetting } from 'CourseAuthoring/utils';
import AppSettingsModal from 'CourseAuthoring/pages-and-resources/app-settings-modal/AppSettingsModal';
import GroupEditor from './GroupEditor';
import messages from './messages';
setupYupExtensions();
function TeamSettings({
intl,
const TeamSettings = ({
onClose,
}) {
}) => {
const intl = useIntl();
const [teamsConfiguration, saveSettings] = useAppSetting('teamsConfiguration');
const blankNewGroup = {
name: '',
description: '',
type: GroupTypes.OPEN,
maxTeamSize: null,
userPartitionId: null,
id: null,
key: uuid(),
};
@@ -38,6 +39,7 @@ function TeamSettings({
type: group.type,
description: group.description,
max_team_size: group.maxTeamSize,
user_partition_id: group.userPartitionId,
}));
return saveSettings({
team_sets: groups,
@@ -105,6 +107,7 @@ function TeamSettings({
)
.when('enabled', {
is: true,
// oxlint-disable-next-line unicorn/no-thenable
then: Yup.array().min(1),
})
.default([])
@@ -161,11 +164,10 @@ function TeamSettings({
}
</AppSettingsModal>
);
}
};
TeamSettings.propTypes = {
intl: intlShape.isRequired,
onClose: PropTypes.func.isRequired,
};
export default injectIntl(TeamSettings);
export default TeamSettings;

View File

@@ -93,6 +93,14 @@ const messages = defineMessages({
id: 'authoring.pagesAndResources.teams.group.types.open',
defaultMessage: 'Open',
},
groupTypeOpenManaged: {
id: 'authoring.pagesAndResources.teams.group.types.open_managed',
defaultMessage: 'Open managed',
},
groupTypeOpenManagedDescription: {
id: 'authoring.pagesAndResources.teams.group.types.open_managed.description',
defaultMessage: 'Only course staff can create teams. Learners can see, join and leave teams.',
},
groupTypeOpenDescription: {
id: 'authoring.pagesAndResources.teams.group.types.open.description',
defaultMessage: 'Learners can create, join, leave, and see other teams',

View File

@@ -0,0 +1,20 @@
{
"name": "@openedx-plugins/course-app-teams",
"version": "0.1.0",
"description": "Teams configuration for courses using it",
"peerDependencies": {
"@edx/frontend-app-authoring": "*",
"@edx/frontend-platform": "*",
"@openedx/paragon": "*",
"formik": "*",
"prop-types": "*",
"react": "*",
"uuid": "*",
"yup": "*"
},
"peerDependenciesMeta": {
"@edx/frontend-app-authoring": {
"optional": true
}
}
}

View File

@@ -0,0 +1,22 @@
import { getConfig } from '@edx/frontend-platform';
import { GroupTypes } from 'CourseAuthoring/data/constants';
/**
* Check if a group type is enabled by the current configuration.
* This is a temporary workaround to disable the OPEN MANAGED team type until it is fully adopted.
* For more information, see: https://openedx.atlassian.net/wiki/spaces/COMM/pages/3885760525/Open+Managed+Group+Type
* @param {string} groupType - the group type to check
* @returns {boolean} - true if the group type is enabled
*/
export const isGroupTypeEnabled = (groupType) => {
const enabledTypesByDefault = [
GroupTypes.OPEN,
GroupTypes.PUBLIC_MANAGED,
GroupTypes.PRIVATE_MANAGED,
];
const enabledTypesByConfig = {
[GroupTypes.OPEN_MANAGED]: getConfig().ENABLE_OPEN_MANAGED_TEAM_TYPE,
};
return enabledTypesByDefault.includes(groupType) || enabledTypesByConfig[groupType] || false;
};

View File

@@ -0,0 +1,39 @@
import { getConfig } from '@edx/frontend-platform';
import { GroupTypes } from 'CourseAuthoring/data/constants';
import { isGroupTypeEnabled } from './utils';
jest.mock('@edx/frontend-platform', () => ({ getConfig: jest.fn() }));
describe('teams utils', () => {
describe('isGroupTypeEnabled', () => {
beforeEach(() => {
jest.clearAllMocks();
});
test('returns true if the group type is enabled', () => {
getConfig.mockReturnValue({ ENABLE_OPEN_MANAGED_TEAM_TYPE: false });
expect(isGroupTypeEnabled(GroupTypes.OPEN)).toBe(true);
expect(isGroupTypeEnabled(GroupTypes.PUBLIC_MANAGED)).toBe(true);
expect(isGroupTypeEnabled(GroupTypes.PRIVATE_MANAGED)).toBe(true);
});
test('returns false if the OPEN_MANAGED group is not enabled', () => {
getConfig.mockReturnValue({ ENABLE_OPEN_MANAGED_TEAM_TYPE: false });
expect(isGroupTypeEnabled(GroupTypes.OPEN_MANAGED)).toBe(false);
});
test('returns true if the OPEN_MANAGED group is enabled', () => {
getConfig.mockReturnValue({ ENABLE_OPEN_MANAGED_TEAM_TYPE: true });
expect(isGroupTypeEnabled(GroupTypes.OPEN_MANAGED)).toBe(true);
});
test('returns false if the group is invalid', () => {
getConfig.mockReturnValue({ ENABLE_OPEN_MANAGED_TEAM_TYPE: true });
expect(isGroupTypeEnabled('FOO')).toBe(false);
});
test('returns false if the group is null', () => {
getConfig.mockReturnValue({ ENABLE_OPEN_MANAGED_TEAM_TYPE: true });
expect(isGroupTypeEnabled(null)).toBe(false);
});
});
});

View File

@@ -1,14 +1,15 @@
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import PropTypes from 'prop-types';
import React from 'react';
import * as Yup from 'yup';
import FormSwitchGroup from '../../generic/FormSwitchGroup';
import { useAppSetting } from '../../utils';
import AppSettingsModal from '../app-settings-modal/AppSettingsModal';
import FormSwitchGroup from 'CourseAuthoring/generic/FormSwitchGroup';
import { useAppSetting } from 'CourseAuthoring/utils';
import AppSettingsModal from 'CourseAuthoring/pages-and-resources/app-settings-modal/AppSettingsModal';
import messages from './messages';
function WikiSettings({ intl, onClose }) {
const WikiSettings = ({ onClose }) => {
const intl = useIntl();
const [enablePublicWiki, saveSetting] = useAppSetting('allowPublicWikiAccess');
const handleSettingsSave = (values) => saveSetting(values.enablePublicWiki);
@@ -32,18 +33,17 @@ function WikiSettings({ intl, onClose }) {
label={intl.formatMessage(messages.enablePublicWikiLabel)}
helpText={intl.formatMessage(messages.enablePublicWikiHelp)}
onChange={handleChange}
onBlue={handleBlur}
onBlur={handleBlur}
checked={values.enablePublicWiki}
/>
)
}
</AppSettingsModal>
);
}
};
WikiSettings.propTypes = {
intl: intlShape.isRequired,
onClose: PropTypes.func.isRequired,
};
export default injectIntl(WikiSettings);
export default WikiSettings;

View File

@@ -26,8 +26,8 @@ const messages = defineMessages({
},
enablePublicWikiHelp: {
id: 'course-authoring.pages-resources.wiki.enable-public-wiki.help',
defaultMessage: `If enabled, edX users can view the course wiki even when
they're not enrolled in the course.`,
defaultMessage: `If enabled, any registered user can view the course wiki
even if they are not enrolled in the course`,
},
});

View File

@@ -0,0 +1,18 @@
{
"name": "@openedx-plugins/course-app-wiki",
"version": "0.1.0",
"description": "Wiki configuration for courses using it",
"peerDependencies": {
"@edx/frontend-app-authoring": "*",
"@edx/frontend-platform": "*",
"@openedx/paragon": "*",
"prop-types": "*",
"react": "*",
"yup": "*"
},
"peerDependenciesMeta": {
"@edx/frontend-app-authoring": {
"optional": true
}
}
}

View File

@@ -0,0 +1,4 @@
Xpert Unit Summaries Configuration Plugin
=========================================
Install this using ``npm install plugins/course-apps/xpert_unit_summary/ --no-save``.

View File

@@ -0,0 +1,41 @@
import React, { useCallback, useContext, useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { useIntl } from '@edx/frontend-platform/i18n';
import { PagesAndResourcesContext } from 'CourseAuthoring/pages-and-resources/PagesAndResourcesProvider';
import { useNavigate } from 'react-router-dom';
import SettingsModal from './settings-modal/SettingsModal';
import messages from './messages';
import { fetchXpertSettings } from './data/thunks';
const XpertUnitSummarySettings = () => {
const intl = useIntl();
const { path: pagesAndResourcesPath, courseId } = useContext(PagesAndResourcesContext);
const dispatch = useDispatch();
const navigate = useNavigate();
useEffect(() => {
dispatch(fetchXpertSettings(courseId));
}, [courseId]);
const handleClose = useCallback(() => {
navigate(pagesAndResourcesPath);
}, [pagesAndResourcesPath]);
return (
<SettingsModal
appId="xpert-unit-summary"
title={intl.formatMessage(messages.heading)}
enableAppHelp={intl.formatMessage(messages.enableXpertUnitSummaryHelp)}
helpPrivacyText={intl.formatMessage(messages.enableXpertUnitSummaryHelpPrivacyLink)}
enableAppLabel={intl.formatMessage(messages.enableXpertUnitSummaryLabel)}
learnMoreText={intl.formatMessage(messages.enableXpertUnitSummaryLink)}
allUnitsEnabledText={intl.formatMessage(messages.allUnitsEnabledByDefault)}
noUnitsEnabledText={intl.formatMessage(messages.noUnitsEnabledByDefault)}
onClose={handleClose}
/>
);
};
export default XpertUnitSummarySettings;

View File

@@ -0,0 +1,282 @@
import ReactDOM from 'react-dom';
import React from 'react';
import { MemoryRouter, Routes, Route } from 'react-router-dom';
import {
getConfig, initializeMockApp, setConfig,
} from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { AppProvider, PageWrap } from '@edx/frontend-platform/react';
import {
findByTestId, queryByTestId, render, waitFor, getByText, fireEvent,
} from '@testing-library/react';
import MockAdapter from 'axios-mock-adapter';
import PagesAndResourcesProvider from 'CourseAuthoring/pages-and-resources/PagesAndResourcesProvider';
import initializeStore from 'CourseAuthoring/store';
import { executeThunk } from 'CourseAuthoring/utils';
import XpertUnitSummarySettings from './Settings';
import * as API from './data/api';
import * as Thunks from './data/thunks';
const courseId = 'course-v1:edX+TestX+Test_Course';
let axiosMock;
let store;
let container;
// Modal creates a portal. Overriding ReactDOM.createPortal allows portals to be tested in jest.
ReactDOM.createPortal = jest.fn(node => node);
function renderComponent() {
const wrapper = render(
<AppProvider store={store} wrapWithRouter={false}>
<PagesAndResourcesProvider courseId={courseId}>
<MemoryRouter initialEntries={['/xpert-unit-summary/settings']}>
<Routes>
<Route
path="/xpert-unit-summary/settings"
element={<PageWrap><XpertUnitSummarySettings courseId={courseId} /></PageWrap>}
/>
<Route
path="/"
element={<PageWrap><div /></PageWrap>}
/>
</Routes>
</MemoryRouter>
</PagesAndResourcesProvider>
</AppProvider>,
);
container = wrapper.container;
}
function generateCourseLevelAPIResponse({
success, enabled,
}) {
return {
response: {
success, enabled,
},
};
}
describe('XpertUnitSummarySettings', () => {
beforeEach(() => {
setConfig({
...getConfig(),
BASE_URL: 'http://test.edx.org',
LMS_BASE_URL: 'http://lmstest.edx.org',
CMS_BASE_URL: 'http://cmstest.edx.org',
LOGIN_URL: 'http://support.edx.org/login',
LOGOUT_URL: 'http://support.edx.org/logout',
REFRESH_ACCESS_TOKEN_ENDPOINT: 'http://support.edx.org/access_token',
ACCESS_TOKEN_COOKIE_NAME: 'cookie',
CSRF_TOKEN_API_PATH: '/',
SUPPORT_URL: 'http://support.edx.org',
});
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: true,
roles: [],
},
});
store = initializeStore({
models: {
courseDetails: {
[courseId]: {
start: Date(),
},
},
},
});
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
});
describe('with successful network connections', () => {
beforeEach(() => {
axiosMock.onGet(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: true,
}));
renderComponent();
});
test('Shows switch on if enabled from backend', async () => {
const enableBadge = await findByTestId(container, 'enable-badge');
expect(container.querySelector('#enable-xpert-unit-summary-toggle').checked).toBeTruthy();
expect(enableBadge).toBeTruthy();
});
test('Shows switch on if disabled from backend', async () => {
axiosMock.onGet(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: false,
}));
renderComponent();
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
expect(container.querySelector('#enable-xpert-unit-summary-toggle').checked).toBeTruthy();
expect(queryByTestId(container, 'enable-badge')).toBeTruthy();
});
test('Shows enable radio selected if enabled from backend', async () => {
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
expect(queryByTestId(container, 'enable-radio').checked).toBeTruthy();
});
test('Shows disable radio selected if enabled from backend', async () => {
axiosMock.onGet(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: false,
}));
renderComponent();
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
expect(queryByTestId(container, 'disable-radio').checked).toBeTruthy();
});
});
describe('first time course configuration', () => {
beforeEach(() => {
axiosMock.onGet(API.getXpertSettingsUrl(courseId))
.reply(400, generateCourseLevelAPIResponse({
success: false,
enabled: undefined,
}));
renderComponent();
});
test('Does not show as enabled if configuration does not exist', async () => {
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
expect(container.querySelector('#enable-xpert-unit-summary-toggle').checked).not.toBeTruthy();
expect(queryByTestId(container, 'enable-badge')).not.toBeTruthy();
});
});
describe('saving configuration changes', () => {
beforeEach(() => {
axiosMock.onGet(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: false,
}));
axiosMock.onPost(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: true,
}));
renderComponent();
});
test('Saving configuration changes', async () => {
jest.spyOn(API, 'postXpertSettings');
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
expect(queryByTestId(container, 'disable-radio').checked).toBeTruthy();
fireEvent.click(queryByTestId(container, 'enable-radio'));
fireEvent.click(getByText(container, 'Save'));
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
expect(API.postXpertSettings).toBeCalled();
});
});
describe('testing configurable gating', () => {
beforeEach(async () => {
axiosMock.onGet(API.getXpertConfigurationStatusUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: true,
}));
jest.spyOn(API, 'getXpertPluginConfigurable');
await executeThunk(Thunks.fetchXpertPluginConfigurable(courseId), store.dispatch);
renderComponent();
});
test('getting Xpert Plugin configurable status', () => {
expect(API.getXpertPluginConfigurable).toBeCalled();
});
});
describe('removing course configuration', () => {
beforeEach(() => {
axiosMock.onGet(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: true,
}));
axiosMock.onDelete(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: undefined,
}));
renderComponent();
});
test('Deleting course configuration', async () => {
jest.spyOn(API, 'deleteXpertSettings');
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
fireEvent.click(container.querySelector('#enable-xpert-unit-summary-toggle'));
fireEvent.click(getByText(container, 'Save'));
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
expect(API.deleteXpertSettings).toBeCalled();
});
});
describe('resetting course units', () => {
test('reset all units to be enabled', async () => {
axiosMock.onGet(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: true,
}));
axiosMock.onPost(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: true,
}));
renderComponent();
jest.spyOn(API, 'postXpertSettings');
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
fireEvent.click(queryByTestId(container, 'reset-units'));
expect(API.postXpertSettings).toBeCalledWith(courseId, { reset: true, enabled: true });
});
test('reset all units to be disabled', async () => {
axiosMock.onGet(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: false,
}));
axiosMock.onPost(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: false,
}));
renderComponent();
jest.spyOn(API, 'postXpertSettings');
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
fireEvent.click(queryByTestId(container, 'reset-units'));
expect(API.postXpertSettings).toBeCalledWith(courseId, { reset: true, enabled: false });
});
});
});

View File

@@ -0,0 +1,13 @@
export default {
id: 'xpert-unit-summary',
enabled: false,
name: 'Xpert unit summaries',
description: 'Use generative AI to summarize course content and reinforce learning.',
allowedOperations: {
enable: true,
configure: true,
},
documentationLinks: {
learnMoreConfiguration: 'https://openai.com/',
},
};

View File

@@ -0,0 +1,41 @@
import { getConfig } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
export function getXpertSettingsUrl(courseId) {
return `${getConfig().STUDIO_BASE_URL}/ai_aside/v1/${courseId}`;
}
export function getXpertConfigurationStatusUrl(courseId) {
return `${getConfig().STUDIO_BASE_URL}/ai_aside/v1/${courseId}/configurable`;
}
export async function getXpertSettings(courseId) {
const { data } = await getAuthenticatedHttpClient()
.get(getXpertSettingsUrl(courseId));
return data;
}
export async function postXpertSettings(courseId, state) {
const { data } = await getAuthenticatedHttpClient()
.post(getXpertSettingsUrl(courseId), {
enabled: state.enabled,
reset: state.reset,
});
return data;
}
export async function getXpertPluginConfigurable(courseId) {
const { data } = await getAuthenticatedHttpClient()
.get(getXpertConfigurationStatusUrl(courseId));
return data;
}
export async function deleteXpertSettings(courseId) {
const { data } = await getAuthenticatedHttpClient()
.delete(getXpertSettingsUrl(courseId));
return data;
}

View File

@@ -0,0 +1,113 @@
import { updateSavingStatus, updateLoadingStatus, updateResetStatus } from 'CourseAuthoring/pages-and-resources/data/slice';
import { RequestStatus } from 'CourseAuthoring/data/constants';
import { addModel, updateModel } from 'CourseAuthoring/generic/model-store';
import {
getXpertSettings, postXpertSettings, getXpertPluginConfigurable, deleteXpertSettings,
} from './api';
export function updateXpertSettings(courseId, state) {
return async (dispatch) => {
dispatch(updateSavingStatus({ status: RequestStatus.IN_PROGRESS }));
try {
const { response } = await postXpertSettings(courseId, state);
const { success } = response;
if (success) {
dispatch(updateModel({ modelType: 'XpertSettings', model: { id: 'xpert-unit-summary', enabled: state.enabled } }));
dispatch(updateSavingStatus({ status: RequestStatus.SUCCESSFUL }));
return true;
}
dispatch(updateSavingStatus({ status: RequestStatus.FAILED }));
return false;
} catch {
dispatch(updateSavingStatus({ status: RequestStatus.FAILED }));
return false;
}
};
}
export function fetchXpertPluginConfigurable(courseId) {
return async (dispatch) => {
let enabled;
dispatch(updateLoadingStatus({ status: RequestStatus.PENDING }));
try {
const { response } = await getXpertPluginConfigurable(courseId);
enabled = response?.enabled;
} catch {
enabled = undefined;
}
dispatch(addModel({
modelType: 'XpertSettings.enabled',
model: {
id: 'xpert-unit-summary',
enabled,
},
}));
};
}
export function fetchXpertSettings(courseId) {
return async (dispatch) => {
let enabled;
dispatch(updateLoadingStatus({ status: RequestStatus.PENDING }));
try {
const { response } = await getXpertSettings(courseId);
enabled = response?.enabled;
} catch {
enabled = undefined;
}
dispatch(addModel({
modelType: 'XpertSettings',
model: {
id: 'xpert-unit-summary',
enabled,
},
}));
dispatch(updateLoadingStatus({ status: RequestStatus.SUCCESSFUL }));
};
}
export function removeXpertSettings(courseId) {
return async (dispatch) => {
dispatch(updateSavingStatus({ status: RequestStatus.PENDING }));
try {
const { response } = await deleteXpertSettings(courseId);
const { success } = response;
if (success) {
const model = { id: 'xpert-unit-summary', enabled: undefined };
dispatch(updateModel({ modelType: 'XpertSettings', model }));
dispatch(updateSavingStatus({ status: RequestStatus.SUCCESSFUL }));
return true;
}
dispatch(updateSavingStatus({ status: RequestStatus.FAILED }));
return false;
} catch {
dispatch(updateSavingStatus({ status: RequestStatus.FAILED }));
return false;
}
};
}
export function resetXpertSettings(courseId, state) {
return async (dispatch) => {
dispatch(updateResetStatus({ status: RequestStatus.PENDING }));
try {
const { response } = await postXpertSettings(courseId, state);
const { success } = response;
if (success) {
dispatch(updateResetStatus({ status: RequestStatus.SUCCESSFUL }));
return true;
}
dispatch(updateResetStatus({ status: RequestStatus.FAILED }));
return false;
} catch {
dispatch(updateResetStatus({ status: RequestStatus.FAILED }));
return false;
}
};
}

View File

@@ -0,0 +1,34 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
heading: {
id: 'course-authoring.pages-resources.xpert-unit-summary.heading',
defaultMessage: 'Configure Xpert unit summaries',
},
enableXpertUnitSummaryLabel: {
id: 'course-authoring.pages-resources.xpert-unit-summary.enable-xpert-unit-summary.label',
defaultMessage: 'Xpert unit summaries',
},
enableXpertUnitSummaryHelp: {
id: 'course-authoring.pages-resources.xpert-unit-summary.enable-xpert-unit-summary.help',
defaultMessage: 'Reinforce learning concepts by sharing text-based course content with OpenAI (via API) to display unit summaries on-demand for learners. Learners can leave feedback about the quality of the AI-generated summaries for use by edX to improve the performance of the tool.',
},
enableXpertUnitSummaryHelpPrivacyLink: {
id: 'course-authoring.pages-resources.xpert-unit-summary.enable-xpert-unit-summary.help.privacylink',
defaultMessage: 'Learn more about OpenAI API data privacy.',
},
enableXpertUnitSummaryLink: {
id: 'course-authoring.pages-resources.xpert-unit-summary.enable-xpert-unit-summary.link',
defaultMessage: 'Learn more about how OpenAI handles data',
},
allUnitsEnabledByDefault: {
id: 'course-authoring.pages-resources.xpert-unit-summary.all-units-enabled-by-default',
defaultMessage: 'All units enabled by default',
},
noUnitsEnabledByDefault: {
id: 'course-authoring.pages-resources.xpert-unit-summary.no-units-enabled-by-default',
defaultMessage: 'No units enabled by default',
},
});
export default messages;

View File

@@ -0,0 +1,21 @@
{
"name": "@openedx-plugins/course-app-xpert_unit_summary",
"version": "0.1.0",
"description": "Xpert Unit Summaries configuration for courses using it",
"peerDependencies": {
"@edx/frontend-app-authoring": "*",
"@edx/frontend-platform": "*",
"@openedx/paragon": "*",
"formik": "*",
"prop-types": "*",
"yup": "*",
"react": "*",
"react-redux": "*",
"react-router-dom": "*"
},
"peerDependenciesMeta": {
"@edx/frontend-app-authoring": {
"optional": true
}
}
}

View File

@@ -0,0 +1,21 @@
const ResetIcon = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
role="img"
focusable="false"
aria-hidden="true"
transform="scale(-1,1)"
{...props}
>
<path
d="M17.65 6.35A7.958 7.958 0 0 0 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0 1 12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"
fill="currentColor"
/>
</svg>
);
export default ResetIcon;

View File

@@ -0,0 +1,454 @@
import { useIntl } from '@edx/frontend-platform/i18n';
import { getExternalLinkUrl } from '@edx/frontend-platform';
import {
ActionRow,
Alert,
Badge,
Form,
Icon,
ModalDialog,
OverlayTrigger,
StatefulButton,
Tooltip,
TransitionReplace,
Hyperlink,
} from '@openedx/paragon';
import {
Info, CheckCircleOutline, SpinnerSimple,
} from '@openedx/paragon/icons';
import { Formik } from 'formik';
import PropTypes from 'prop-types';
import React, {
useContext, useEffect, useRef, useState,
} from 'react';
import { useDispatch, useSelector } from 'react-redux';
import * as Yup from 'yup';
import { RequestStatus } from 'CourseAuthoring/data/constants';
import ConnectionErrorAlert from 'CourseAuthoring/generic/ConnectionErrorAlert';
import FormSwitchGroup from 'CourseAuthoring/generic/FormSwitchGroup';
import Loading from 'CourseAuthoring/generic/Loading';
import { useModel } from 'CourseAuthoring/generic/model-store';
import PermissionDeniedAlert from 'CourseAuthoring/generic/PermissionDeniedAlert';
import { useIsMobile } from 'CourseAuthoring/utils';
import { getLoadingStatus, getSavingStatus, getResetStatus } from 'CourseAuthoring/pages-and-resources/data/selectors';
import { updateSavingStatus, updateResetStatus } from 'CourseAuthoring/pages-and-resources/data/slice';
import AppConfigFormDivider from 'CourseAuthoring/pages-and-resources/discussions/app-config-form/apps/shared/AppConfigFormDivider';
import { PagesAndResourcesContext } from 'CourseAuthoring/pages-and-resources/PagesAndResourcesProvider';
import { updateXpertSettings, resetXpertSettings, removeXpertSettings } from '../data/thunks';
import messages from './messages';
import appInfo from '../appInfo';
import ResetIcon from './ResetIcon';
import './SettingsModal.scss';
const AppSettingsForm = ({
formikProps, children, showForm,
}) => children && (
<TransitionReplace>
{showForm ? (
<React.Fragment key="app-enabled">
{children(formikProps)}
</React.Fragment>
) : (
<React.Fragment key="app-disabled" />
)}
</TransitionReplace>
);
AppSettingsForm.propTypes = {
// Ignore the warning here since we're just passing along the props as-is and the child component should validate
// eslint-disable-next-line react/forbid-prop-types
formikProps: PropTypes.object.isRequired,
showForm: PropTypes.bool.isRequired,
children: PropTypes.func,
};
AppSettingsForm.defaultProps = {
children: null,
};
const SettingsModalBase = ({
title, onClose, variant, isMobile, children, footer,
}) => {
const intl = useIntl();
return (
<ModalDialog
title={title}
isOpen
onClose={onClose}
size="lg"
variant={variant}
hasCloseButton={isMobile}
isFullscreenOnMobile
>
<ModalDialog.Header>
<ModalDialog.Title data-testid="modal-title">
{title}
</ModalDialog.Title>
</ModalDialog.Header>
<ModalDialog.Body>
{children}
</ModalDialog.Body>
<ModalDialog.Footer className="p-4">
<ActionRow>
<ModalDialog.CloseButton variant="tertiary">
{intl.formatMessage(messages.cancel)}
</ModalDialog.CloseButton>
{footer}
</ActionRow>
</ModalDialog.Footer>
</ModalDialog>
);
};
SettingsModalBase.propTypes = {
title: PropTypes.string.isRequired,
onClose: PropTypes.func.isRequired,
variant: PropTypes.oneOf(['default', 'dark']).isRequired,
isMobile: PropTypes.bool.isRequired,
children: PropTypes.node.isRequired,
footer: PropTypes.node,
};
SettingsModalBase.defaultProps = {
footer: null,
};
const ResetUnitsButton = ({
courseId,
checked,
visible,
}) => {
const intl = useIntl();
const resetStatusRequestStatus = useSelector(getResetStatus);
const dispatch = useDispatch();
useEffect(() => {
if (resetStatusRequestStatus === RequestStatus.SUCCESSFUL) {
setTimeout(() => {
dispatch(updateResetStatus({ status: '' }));
}, 2000);
}
}, [resetStatusRequestStatus]);
const handleResetUnits = () => {
dispatch(resetXpertSettings(courseId, { enabled: checked === 'true', reset: true }));
};
const getResetButtonState = () => {
switch (resetStatusRequestStatus) {
case RequestStatus.PENDING:
return 'pending';
case RequestStatus.SUCCESSFUL:
return 'finish';
default:
return 'default';
}
};
if (!visible) { return null; }
const messageKey = checked === 'true' ? 'resetAllUnitsTooltipChecked' : 'resetAllUnitsTooltipUnchecked';
return (
<OverlayTrigger
placement="right"
overlay={(
<Tooltip
id={`tooltip-reset-${checked}`}
className="reset-tooltip"
>
{intl.formatMessage(messages[messageKey])}
</Tooltip>
)}
>
<StatefulButton
className="reset-units-button"
labels={{
default: intl.formatMessage(messages.resetAllUnits),
pending: '',
finish: intl.formatMessage(messages.reset),
}}
icons={{
default: <Icon src={ResetIcon} />,
pending: <Icon src={SpinnerSimple} className="icon-spin" />,
finish: <Icon src={CheckCircleOutline} />,
}}
state={getResetButtonState()}
onClick={handleResetUnits}
disabledStates={['pending', 'finish']}
variant="outline"
data-testid="reset-units"
/>
</OverlayTrigger>
);
};
ResetUnitsButton.propTypes = {
courseId: PropTypes.string.isRequired,
checked: PropTypes.oneOf(['true', 'false']).isRequired,
visible: PropTypes.bool,
};
ResetUnitsButton.defaultProps = {
visible: false,
};
const SettingsModal = ({
appId,
title,
children,
configureBeforeEnable,
initialValues,
validationSchema,
onClose,
onSettingsSave,
enableAppLabel,
enableAppHelp,
learnMoreText,
helpPrivacyText,
enableReinitialize,
allUnitsEnabledText,
noUnitsEnabledText,
}) => {
const intl = useIntl();
const { courseId } = useContext(PagesAndResourcesContext);
const loadingStatus = useSelector(getLoadingStatus);
const updateSettingsRequestStatus = useSelector(getSavingStatus);
const alertRef = useRef(null);
const [saveError, setSaveError] = useState(false);
const dispatch = useDispatch();
const submitButtonState = updateSettingsRequestStatus === RequestStatus.IN_PROGRESS ? 'pending' : 'default';
const isMobile = useIsMobile();
const modalVariant = isMobile ? 'dark' : 'default';
const xpertSettings = useModel('XpertSettings', appId);
useEffect(() => {
if (updateSettingsRequestStatus === RequestStatus.SUCCESSFUL) {
dispatch(updateSavingStatus({ status: '' }));
onClose();
}
}, [updateSettingsRequestStatus]);
const handleFormSubmit = async ({ enabled, checked, ...rest }) => {
let success;
const values = { ...rest, enabled: enabled ? checked === 'true' : undefined };
if (enabled) {
// oxlint-disable-next-line @typescript-eslint/await-thenable - this dispatch() IS returning a promise.
success = await dispatch(updateXpertSettings(courseId, values));
} else {
// oxlint-disable-next-line @typescript-eslint/await-thenable - this dispatch() IS returning a promise.
success = await dispatch(removeXpertSettings(courseId));
}
if (onSettingsSave) {
success = success && await onSettingsSave(values);
}
setSaveError(!success);
!success && alertRef?.current.scrollIntoView(); // eslint-disable-line @typescript-eslint/no-unused-expressions
};
const handleFormikSubmit = ({ handleSubmit, errors }) => async (event) => {
// If submitting the form with errors, show the alert and scroll to it.
await handleSubmit(event);
if (Object.keys(errors).length > 0) {
setSaveError(true);
alertRef?.current.scrollIntoView?.(); // eslint-disable-line no-unused-expressions
}
};
const learnMoreLink = appInfo.documentationLinks?.learnMoreConfiguration && (
<div className="py-1">
<Hyperlink
className="text-primary-500"
destination={appInfo.documentationLinks.learnMoreConfiguration}
target="_blank"
rel="noreferrer noopener"
>
{learnMoreText}
</Hyperlink>
</div>
);
const helpPrivacyLink = (
<div className="py-1">
<Hyperlink
className="text-primary-500"
destination={getExternalLinkUrl('https://openai.com/api-data-privacy')}
target="_blank"
rel="noreferrer noopener"
>
{helpPrivacyText}
</Hyperlink>
</div>
);
if (loadingStatus === RequestStatus.SUCCESSFUL) {
return (
<Formik
initialValues={{
enabled: xpertSettings?.enabled !== undefined,
checked: xpertSettings?.enabled?.toString() || 'true',
...initialValues,
}}
validationSchema={
Yup.object()
.shape({
enabled: Yup.boolean(),
checked: Yup.string().oneOf(['true', 'false']),
...validationSchema,
})
}
onSubmit={handleFormSubmit}
enableReinitialize={enableReinitialize}
>
{(formikProps) => (
<Form onSubmit={handleFormikSubmit(formikProps)}>
<SettingsModalBase
title={title}
isOpen
onClose={onClose}
variant={modalVariant}
isMobile={isMobile}
isFullscreenOnMobile
intl={intl}
footer={(
<StatefulButton
labels={{
default: intl.formatMessage(messages.save),
pending: intl.formatMessage(messages.saving),
complete: intl.formatMessage(messages.saved),
}}
state={submitButtonState}
onClick={handleFormikSubmit(formikProps)}
disabled={!formikProps.dirty}
/>
)}
>
{saveError && (
<Alert variant="danger" icon={Info} ref={alertRef}>
<Alert.Heading>
{formikProps.errors.enabled?.title || intl.formatMessage(messages.errorSavingTitle)}
</Alert.Heading>
{formikProps.errors.enabled?.message || intl.formatMessage(messages.errorSavingMessage)}
</Alert>
)}
<FormSwitchGroup
id={`enable-${appId}-toggle`}
name="enabled"
onChange={formikProps.handleChange}
onBlur={formikProps.handleBlur}
checked={formikProps.values.enabled}
label={(
<div className="d-flex align-items-center">
{enableAppLabel}
{formikProps.values.enabled && (
<Badge className="ml-2" variant="success" data-testid="enable-badge">
{intl.formatMessage(messages.enabled)}
</Badge>
)}
</div>
)}
helpText={(
<div>
<p>{enableAppHelp}</p>
{helpPrivacyLink}
{learnMoreLink}
</div>
)}
/>
{(formikProps.values.enabled || configureBeforeEnable) && (
<Form.RadioSet
name="checked"
onChange={formikProps.handleChange}
onBlur={formikProps.handleBlur}
value={formikProps.values.checked}
>
<Form.Radio
className="summary-radio m-2 px-3"
data-testid="enable-radio"
value="true"
>
{allUnitsEnabledText}
<ResetUnitsButton
courseId={courseId}
checked={formikProps.values.checked}
visible={formikProps.values.checked === 'true'}
/>
</Form.Radio>
<Form.Radio
className="summary-radio m-2 px-3"
data-testid="disable-radio"
value="false"
>
{noUnitsEnabledText}
<ResetUnitsButton
courseId={courseId}
checked={formikProps.values.checked}
visible={formikProps.values.checked === 'false'}
/>
</Form.Radio>
</Form.RadioSet>
)}
{(formikProps.values.enabled || configureBeforeEnable) && children
&& <AppConfigFormDivider marginAdj={{ default: 0, sm: 0 }} />}
<AppSettingsForm formikProps={formikProps} showForm={formikProps.values.enabled || configureBeforeEnable}>
{children}
</AppSettingsForm>
</SettingsModalBase>
</Form>
)}
</Formik>
);
}
return (
<SettingsModalBase
intl={intl}
title={title}
isOpen
onClose={onClose}
size="sm"
variant={modalVariant}
isMobile={isMobile}
isFullscreenOnMobile
>
{loadingStatus === RequestStatus.IN_PROGRESS && <Loading />}
{loadingStatus === RequestStatus.FAILED && <ConnectionErrorAlert />}
{loadingStatus === RequestStatus.DENIED && <PermissionDeniedAlert />}
</SettingsModalBase>
);
};
SettingsModal.propTypes = {
title: PropTypes.string.isRequired,
appId: PropTypes.string.isRequired,
children: PropTypes.func,
onSettingsSave: PropTypes.func,
initialValues: PropTypes.shape({}),
validationSchema: PropTypes.shape({}),
onClose: PropTypes.func.isRequired,
enableAppLabel: PropTypes.string.isRequired,
enableAppHelp: PropTypes.string.isRequired,
learnMoreText: PropTypes.string.isRequired,
helpPrivacyText: PropTypes.string.isRequired,
allUnitsEnabledText: PropTypes.string.isRequired,
noUnitsEnabledText: PropTypes.string.isRequired,
configureBeforeEnable: PropTypes.bool,
enableReinitialize: PropTypes.bool,
};
SettingsModal.defaultProps = {
children: null,
onSettingsSave: null,
initialValues: {},
validationSchema: {},
configureBeforeEnable: false,
enableReinitialize: false,
};
export default SettingsModal;

View File

@@ -0,0 +1,44 @@
@import "~@openedx/paragon/styles/scss/core/utilities-only";
.summary-radio {
display: flex;
align-items: center;
width: 100%;
border-width: $border-width;
border-color: $border-color;
border-radius: $border-radius;
border-style: solid;
&:has(input:checked) {
border-width: 3px;
border-color: theme-color("primary");
}
> div {
flex: 1;
> label {
min-height: 80px;
flex-wrap: wrap;
justify-content: space-between;
}
}
}
.reset-units-button {
color: $link-color;
border-width: $border-width;
border-color: $border-color;
border-radius: $border-radius;
border-style: solid;
}
.reset-tooltip {
.arrow::before {
border-right-color: #00262B;
}
.tooltip-inner {
background-color: #00262B;
}
}

View File

@@ -0,0 +1,58 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
cancel: {
id: 'course-authoring.pages-resources.app-settings-modal.button.cancel',
defaultMessage: 'Cancel',
},
save: {
id: 'course-authoring.pages-resources.app-settings-modal.button.save',
defaultMessage: 'Save',
},
saving: {
id: 'course-authoring.pages-resources.app-settings-modal.button.saving',
defaultMessage: 'Saving',
},
saved: {
id: 'course-authoring.pages-resources.app-settings-modal.button.saved',
defaultMessage: 'Saved',
},
retry: {
id: 'course-authoring.pages-resources.app-settings-modal.button.retry',
defaultMessage: 'Retry',
},
enabled: {
id: 'course-authoring.pages-resources.app-settings-modal.badge.enabled',
defaultMessage: 'Enabled',
},
disabled: {
id: 'course-authoring.pages-resources.app-settings-modal.badge.disabled',
defaultMessage: 'Disabled',
},
resetAllUnits: {
id: 'course-authoring.pages-resources.app-settings-modal.reset-all-units',
defaultMessage: 'Reset all units',
},
resetAllUnitsTooltipChecked: {
id: 'course-authoring.pages-resources.app-settings-modal.reset-all-units-tooltip.checked',
defaultMessage: 'Immediately reset any unit-level changes and checked "Enable summaries" on all units.',
},
resetAllUnitsTooltipUnchecked: {
id: 'course-authoring.pages-resources.app-settings-modal.reset-all-units-tooltip.unchecked',
defaultMessage: 'Immediately reset any unit-level changes and unchecked "Enable summaries" on all units.',
},
reset: {
id: 'course-authoring.pages-resources.app-settings-modal.reset',
defaultMessage: 'Reset',
},
errorSavingTitle: {
id: 'course-authoring.pages-resources.app-settings-modal.save-error.title',
defaultMessage: 'We couldn\'t apply your changes.',
},
errorSavingMessage: {
id: 'course-authoring.pages-resources.app-settings-modal.save-error.message',
defaultMessage: 'Please check your entries and try again.',
},
});
export default messages;

View File

@@ -1,10 +1,10 @@
<!doctype html>
<html lang="en-us">
<head>
<title>Course Authoring | edX</title>
<title>Course Authoring | <%= process.env.SITE_NAME %></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="<%= process.env.FAVICON_URL %>" type="image/x-icon" />
<link rel="shortcut icon" href="<%=htmlWebpackPlugin.options.FAVICON_URL%>" type="image/x-icon" />
</head>
<body>
<div id="root"></div>

View File

@@ -1,19 +1,24 @@
{
"extends": [
"config:base",
"schedule:daily",
"schedule:weekly",
":rebaseStalePrs",
":semanticCommits"
":semanticCommits",
":dependencyDashboard"
],
"timezone": "America/New_York",
"patch": {
"automerge": true
"automerge": false
},
"rebaseStalePrs": true,
"packageRules": [
{
"matchPackagePatterns": ["@edx"],
"extends": [
"schedule:daily"
],
"matchPackagePatterns": ["@edx", "@openedx"],
"matchUpdateTypes": ["minor", "patch"],
"automerge": true
"automerge": false
}
]
}

View File

@@ -0,0 +1,172 @@
import { getConfig } from '@edx/frontend-platform';
import {
createContext, useContext, useMemo, useState,
} from 'react';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { useCreateCourseBlock } from '@src/course-outline/data/apiHooks';
import { useSelector } from 'react-redux';
import { useNavigate } from 'react-router';
import { getOutlineIndexData } from '@src/course-outline/data/selectors';
import { useToggleWithValue } from '@src/hooks';
import { SelectionState, type UnitXBlock, type XBlock } from '@src/data/types';
import { CourseDetailsData } from './data/api';
import { useCourseDetails, useWaffleFlags } from './data/apiHooks';
import { RequestStatusType } from './data/constants';
type ModalState = {
value?: XBlock | UnitXBlock;
subsectionId?: string;
sectionId?: string;
};
export type CourseAuthoringContextData = {
/** The ID of the current course */
courseId: string;
courseUsageKey: string;
courseDetails?: CourseDetailsData;
courseDetailStatus: RequestStatusType;
canChangeProviders: boolean;
handleAddAndOpenUnit: ReturnType<typeof useCreateCourseBlock>;
handleAddBlock: ReturnType<typeof useCreateCourseBlock>;
openUnitPage: (locator: string) => void;
getUnitUrl: (locator: string) => string;
isUnlinkModalOpen: boolean;
currentUnlinkModalData?: ModalState;
openUnlinkModal: (value: ModalState) => void;
closeUnlinkModal: () => void;
isPublishModalOpen: boolean;
currentPublishModalData?: ModalState;
openPublishModal: (value: ModalState) => void;
closePublishModal: () => void;
currentSelection?: SelectionState;
setCurrentSelection: React.Dispatch<React.SetStateAction<SelectionState | undefined>>;
};
/**
* Course Authoring Context.
* Always available when we're in the context of a single course.
*
* Get this using `useCourseAuthoringContext()`
*
*/
const CourseAuthoringContext = createContext<CourseAuthoringContextData | undefined>(undefined);
type CourseAuthoringProviderProps = {
children?: React.ReactNode;
courseId: string;
};
export const CourseAuthoringProvider = ({
children,
courseId,
}: CourseAuthoringProviderProps) => {
const navigate = useNavigate();
const waffleFlags = useWaffleFlags();
const { data: courseDetails, status: courseDetailStatus } = useCourseDetails(courseId);
const canChangeProviders = getAuthenticatedUser().administrator || new Date(courseDetails?.start ?? 0) > new Date();
const { courseStructure } = useSelector(getOutlineIndexData);
const { id: courseUsageKey } = courseStructure || {};
const [
isUnlinkModalOpen,
currentUnlinkModalData,
openUnlinkModal,
closeUnlinkModal,
] = useToggleWithValue<ModalState>();
const [
isPublishModalOpen,
currentPublishModalData,
openPublishModal,
closePublishModal,
] = useToggleWithValue<ModalState>();
/**
* This will hold the state of current item that is being operated on,
* For example:
* - the details of container that is being edited.
* - the details of container of which see more dropdown is open.
* It is mostly used in modals which should be soon be replaced with its equivalent in sidebar.
*/
const [currentSelection, setCurrentSelection] = useState<SelectionState | undefined>();
const getUnitUrl = (locator: string) => {
if (getConfig().ENABLE_UNIT_PAGE === 'true' && waffleFlags.useNewUnitPage) {
// instanbul ignore next
return `/course/${courseId}/container/${locator}`;
}
return `${getConfig().STUDIO_BASE_URL}/container/${locator}`;
};
/**
* Open the unit page for a given locator.
*/
const openUnitPage = async (locator: string) => {
const url = getUnitUrl(locator);
if (getConfig().ENABLE_UNIT_PAGE === 'true' && waffleFlags.useNewUnitPage) {
// instanbul ignore next
navigate(url);
} else {
window.location.assign(url);
}
};
/**
* import a unit block from library and redirect user to this unit page.
*/
const handleAddAndOpenUnit = useCreateCourseBlock(courseId, openUnitPage);
const handleAddBlock = useCreateCourseBlock(courseId);
const context = useMemo<CourseAuthoringContextData>(() => ({
courseId,
courseUsageKey,
courseDetails,
courseDetailStatus,
canChangeProviders,
handleAddBlock,
handleAddAndOpenUnit,
getUnitUrl,
openUnitPage,
isUnlinkModalOpen,
openUnlinkModal,
closeUnlinkModal,
currentUnlinkModalData,
isPublishModalOpen,
currentPublishModalData,
openPublishModal,
closePublishModal,
currentSelection,
setCurrentSelection,
}), [
courseId,
courseUsageKey,
courseDetails,
courseDetailStatus,
canChangeProviders,
handleAddBlock,
handleAddAndOpenUnit,
getUnitUrl,
openUnitPage,
isUnlinkModalOpen,
openUnlinkModal,
closeUnlinkModal,
currentUnlinkModalData,
isPublishModalOpen,
currentPublishModalData,
openPublishModal,
closePublishModal,
currentSelection,
setCurrentSelection,
]);
return (
<CourseAuthoringContext.Provider value={context}>
{children}
</CourseAuthoringContext.Provider>
);
};
export function useCourseAuthoringContext(): CourseAuthoringContextData {
const ctx = useContext(CourseAuthoringContext);
if (ctx === undefined) {
/* istanbul ignore next */
throw new Error('useCourseAuthoringContext() was used in a component without a <CourseAuthoringProvider> ancestor.');
}
return ctx;
}

View File

@@ -1,73 +0,0 @@
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import Footer from '@edx/frontend-component-footer';
import { useDispatch, useSelector } from 'react-redux';
import {
useLocation,
} from 'react-router-dom';
import Header from './studio-header/Header';
import { fetchCourseDetail } from './data/thunks';
import { useModel } from './generic/model-store';
import PermissionDeniedAlert from './generic/PermissionDeniedAlert';
import { getCourseAppsApiStatus, getLoadingStatus } from './pages-and-resources/data/selectors';
import { RequestStatus } from './data/constants';
import Loading from './generic/Loading';
export default function CourseAuthoringPage({ courseId, children }) {
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchCourseDetail(courseId));
}, [courseId]);
const courseDetail = useModel('courseDetails', courseId);
const courseNumber = courseDetail ? courseDetail.number : null;
const courseOrg = courseDetail ? courseDetail.org : null;
const courseTitle = courseDetail ? courseDetail.name : courseId;
const courseAppsApiStatus = useSelector(getCourseAppsApiStatus);
const inProgress = useSelector(getLoadingStatus) === RequestStatus.IN_PROGRESS;
const { pathname } = useLocation();
if (courseAppsApiStatus === RequestStatus.DENIED) {
return (
<PermissionDeniedAlert />
);
}
const AppHeader = () => (
<Header
courseNumber={courseNumber}
courseOrg={courseOrg}
courseTitle={courseTitle}
courseId={courseId}
/>
);
const AppFooter = () => (
<div className="mt-6">
<Footer />
</div>
);
return (
<div className="bg-light-200">
{/* While V2 Editors are tempoarily served from thier own pages
using url pattern containing /editor/,
we shouldn't have the header and footer on these pages.
This functionality will be removed in TNL-9591 */}
{inProgress ? !pathname.includes('/editor/') && <Loading /> : <AppHeader />}
{children}
{!inProgress && <AppFooter />}
</div>
);
}
CourseAuthoringPage.propTypes = {
children: PropTypes.node,
courseId: PropTypes.string.isRequired,
};
CourseAuthoringPage.defaultProps = {
children: null,
};

Some files were not shown because too many files have changed in this diff Show More