Compare commits

...

6 Commits

Author SHA1 Message Date
obscherler
e8e5337b7b fix: Update frontend-platform to version 8.3.8 for fixes with theme URL loading. (#825)
8.3.7: Simplify the logic for Paragon `fallbackThemeUrl` to always rely on `window.location?.origin`;
8.3.8: Allow the creation of URLs with only `brandOverride` definition.
2025-11-06 09:50:20 -05:00
Brian Smith
88bf980546 feat!: add design tokens support (#777)
BREAKING CHANGE: Pre-design-tokens theming is no longer supported.

Co-authored-by: Diana Olarte <dcoa@live.com>
2025-07-30 12:43:11 -05:00
Brian Smith
bad12462f5 feat: import FooterSlot from component package instead of slot package (#765) 2025-04-24 11:50:49 -04:00
renovate[bot]
ec915f622b fix(deps): update dependency @edx/frontend-component-header to v6.4.0 (#766)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-23 20:15:13 +00:00
Régis Behmo
60da5eafc4 chore: remove husky 🪓🐶 (#761) 2025-04-09 14:53:26 -04:00
Hunia Fatima
05cf174335 feat: upgrade react to v18 (#759) 2025-04-09 10:11:28 -04:00
14 changed files with 4969 additions and 2195 deletions

2
.env
View File

@@ -22,3 +22,5 @@ USER_INFO_COOKIE_NAME=''
SUPPORT_URL=''
LEARNER_FEEDBACK_URL=''
STAFF_FEEDBACK_URL=''
# Fallback in local style files
PARAGON_THEME_URLS={}

View File

@@ -23,3 +23,5 @@ USER_INFO_COOKIE_NAME='edx-user-info'
SUPPORT_URL='https://support.edx.org'
LEARNER_FEEDBACK_URL=''
STAFF_FEEDBACK_URL=''
# Fallback in local style files
PARAGON_THEME_URLS={}

1
.gitignore vendored
View File

@@ -6,6 +6,7 @@ node_modules
npm-debug.log
coverage
module.config.js
env.config.*
dist/
src/i18n/transifex_input.json

7024
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -19,11 +19,6 @@
"dev": "PUBLIC_PATH=/discussions/ MFE_CONFIG_API_URL='http://localhost:8000/api/mfe_config/v1' fedx-scripts webpack-dev-server --progress --host apps.local.openedx.io",
"test": "fedx-scripts jest --coverage --passWithNoTests"
},
"husky": {
"hooks": {
"pre-commit": "npm run lint"
}
},
"author": "edX",
"license": "AGPL-3.0",
"homepage": "https://github.com/openedx/frontend-app-discussions#readme",
@@ -35,14 +30,13 @@
},
"dependencies": {
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
"@edx/frontend-component-footer": "^14.3.0",
"@edx/frontend-component-footer": "^14.6.0",
"@edx/frontend-component-header": "^6.2.0",
"@edx/frontend-platform": "^8.3.1",
"@edx/frontend-platform": "^8.3.8",
"@edx/openedx-atlas": "^0.6.0",
"@openedx/frontend-slot-footer": "^1.0.2",
"@openedx/paragon": "^22.16.0",
"@openedx/paragon": "^23.4.5",
"@reduxjs/toolkit": "1.9.7",
"@tinymce/tinymce-react": "3.13.1",
"@tinymce/tinymce-react": "5.1.1",
"babel-polyfill": "6.26.0",
"classnames": "2.5.1",
"core-js": "3.21.1",
@@ -51,8 +45,8 @@
"lodash.snakecase": "4.1.1",
"prop-types": "15.8.1",
"raw-loader": "4.0.2",
"react": "17.0.2",
"react-dom": "17.0.2",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-helmet": "6.1.0",
"react-redux": "7.2.9",
"react-router": "6.18.0",
@@ -68,14 +62,13 @@
"@edx/reactifex": "1.1.0",
"@openedx/frontend-build": "^14.3.3",
"@testing-library/jest-dom": "5.17.0",
"@testing-library/react": "12.1.5",
"@testing-library/react": "14.3.1",
"@testing-library/user-event": "13.5.0",
"axios": "^0.28.0",
"axios-mock-adapter": "1.22.0",
"babel-plugin-react-intl": "8.2.25",
"eslint-plugin-simple-import-sort": "7.0.0",
"glob": "7.2.0",
"husky": "7.0.4",
"jest": "29.7.0",
"rosie": "2.1.1"
}

View File

@@ -1,24 +1,16 @@
@import "~@edx/brand/paragon/fonts.scss";
@import "~@edx/brand/paragon/variables.scss";
@import "~@openedx/paragon/scss/core/core.scss";
@import "~@edx/brand/paragon/overrides.scss";
$fa-font-path: "~font-awesome/fonts";
@import "~font-awesome/scss/font-awesome";
.course-tabs-navigation {
border-bottom: solid 1px #eaeaea;
.nav a,
.nav button {
&:hover {
background-color: $light-400;
background-color: var(--pgn-color-light-400);
}
}
.nav a {
&:not(.active):hover {
background-color: $light-400;
background-color: var(--pgn-color-light-400);
border-bottom: none;
}
}
@@ -30,7 +22,7 @@ $fa-font-path: "~font-awesome/fonts";
.nav-link {
border-bottom: 4px solid transparent;
border-top: 4px solid transparent;
color: $gray-700;
color: var(--pgn-color-gray-700);
// temporary until we can remove .btn class from dropdowns
border-left: 0;
@@ -40,9 +32,9 @@ $fa-font-path: "~font-awesome/fonts";
&:hover,
&:focus,
&.active {
font-weight: $font-weight-normal;
color: $primary-500;
border-bottom-color: $primary-500;
font-weight: var(--pgn-typography-font-weight-normal);
color: var(--pgn-color-primary-500);
border-bottom-color: var(--pgn-color-primary-500);
}
}
}

View File

@@ -1,6 +1,5 @@
import { render, screen } from '@testing-library/react';
import MockAdapter from 'axios-mock-adapter';
import { act } from 'react-dom/test-utils';
import { IntlProvider } from 'react-intl';
import { Context as ResponsiveContext } from 'react-responsive';
import { MemoryRouter } from 'react-router-dom';
@@ -85,7 +84,7 @@ describe('DiscussionSidebar', () => {
},
})]);
renderComponent();
await act(async () => expect(await screen.findAllByText('Thread by other users')).toBeTruthy());
await screen.findAllByText('Thread by other users');
expect(screen.queryByText('Thread by abc123')).not.toBeInTheDocument();
});
@@ -100,7 +99,7 @@ describe('DiscussionSidebar', () => {
},
})]);
renderComponent();
await act(async () => expect(await screen.findAllByText('Thread by other users')).toBeTruthy());
await screen.findAllByText('Thread by other users');
expect(screen.queryByText('Thread by abc123')).not.toBeInTheDocument();
expect(container.querySelectorAll('.discussion-post')).toHaveLength(postCount);
});

View File

@@ -27,7 +27,7 @@ import { selectPostEditorVisible } from '../posts/data/selectors';
import { isCourseStatusValid } from '../utils';
import useFeedbackWrapper from './FeedbackWrapper';
const FooterSlot = lazy(() => import('@openedx/frontend-slot-footer'));
const FooterSlot = lazy(() => import('@edx/frontend-component-footer').then(module => ({ default: module.FooterSlot })));
const PostActionsBar = lazy(() => import('../posts/post-actions-bar/PostActionsBar'));
const CourseTabsNavigation = lazy(() => import('../../components/NavigationBar/CourseTabsNavigation'));
const LegacyBreadcrumbMenu = lazy(() => import('../navigation/breadcrumb-menu/LegacyBreadcrumbMenu'));

View File

@@ -229,7 +229,7 @@ describe('DiscussionsHome', () => {
await screen.findByText('Nothing here yet');
await act(async () => {
fireEvent.click(await screen.findByText('Add a post'));
fireEvent.click((await screen.findAllByText('Add a post'))[0]);
});
await waitFor(() => expect(container.querySelector('.post-form')).toBeInTheDocument());

View File

@@ -92,7 +92,7 @@ const CommentsView = ({ threadType }) => {
variant="plain"
block="true"
className="card mb-4 px-0 border-0 py-10px mt-2 font-style font-weight-500
line-height-24 text-primary-500"
line-height-24 text-primary-500 bg-white"
onClick={handleAddResponse}
data-testid="add-response"
>

View File

@@ -1,8 +1,10 @@
import 'core-js/stable';
import 'regenerator-runtime/runtime';
import React from 'react';
import ReactDOM from 'react-dom';
import React, { StrictMode } from 'react';
// eslint-disable-next-line import/no-unresolved
import { createRoot } from 'react-dom/client';
import {
APP_INIT_ERROR, APP_READY, initialize, mergeConfig,
@@ -17,18 +19,20 @@ import store from './store';
import './index.scss';
const rootNode = createRoot(document.getElementById('root'));
subscribe(APP_READY, () => {
ReactDOM.render(
<AppProvider store={store}>
<Head />
<DiscussionsHome />
</AppProvider>,
document.getElementById('root'),
rootNode.render(
<StrictMode>
<AppProvider store={store}>
<Head />
<DiscussionsHome />
</AppProvider>
</StrictMode>,
);
});
subscribe(APP_INIT_ERROR, (error) => {
ReactDOM.render(<ErrorPage message={error.message} />, document.getElementById('root'));
rootNode.render(<ErrorPage message={error.message} />);
});
initialize({

View File

@@ -1,13 +1,9 @@
@import "~@edx/brand/paragon/fonts.scss";
@import "~@edx/brand/paragon/variables.scss";
@import "~@openedx/paragon/scss/core/core.scss";
@import "~@edx/brand/paragon/overrides.scss";
@use "@openedx/paragon/styles/css/core/custom-media-breakpoints" as paragonCustomMediaBreakpoints;
@import "~@edx/frontend-component-footer/dist/footer";
@import "~@edx/frontend-component-header/dist/index";
$fa-font-path: "~font-awesome/fonts";
@import "~font-awesome/scss/font-awesome";
body,
#main
@@ -28,6 +24,10 @@ body,
font-size: 16px !important;
}
.btn-plain {
background-color: var(--pgn-color-card-bg-base) !important;
}
#post,
#comment,
#reply,
@@ -41,23 +41,23 @@ body,
}
.text-staff-color {
color: $warning-700;
color: var(--pgn-color-warning-700);
}
.outline-staff-color {
outline: $warning-700 solid 2px;
outline: var(--pgn-color-warning-700) solid 2px;
}
.text-TA-color {
color: $success-700;
color: var(--pgn-color-success-700);
}
.outline-TA-color {
outline: $success-700 solid 2px;
outline: var(--pgn-color-success-700) solid 2px;
}
.outline-anonymous {
outline: $light-400 solid 2px;
outline: var(--pgn-color-light-400) solid 2px;
}
.font-size-8 {
@@ -173,7 +173,7 @@ body,
}
.learner > a:hover {
background-color: $light-300;
background-color: var(--pgn-color-light-300);
}
.py-10px {
@@ -252,12 +252,12 @@ header {
}
.border-light-400-2 {
border: 2px solid $light-400 !important;
border: 2px solid var(--pgn-color-light-400) !important;
border-width: 2px !important;
}
.border-primary-500-2 {
border: 2px solid $primary-500 !important;
border: 2px solid var(--pgn-color-primary-500) !important;
border-width: 2px !important;
}
@@ -383,8 +383,8 @@ header {
}
.btn-icon.btn-icon-primary:hover {
background-color: $light-300 !important;
color: $primary-500 !important
background-color: var(--pgn-color-light-300) !important;
color: var(--pgn-color-primary-500) !important
}
@@ -427,38 +427,38 @@ header {
}
.hover-button:hover {
background-color: $light-300 !important;
background-color: var(--pgn-color-light-300) !important;
height: 36px !important;
border: none !important;
}
.btn-tertiary:hover {
background-color: $light-300 !important;
background-color: var(--pgn-color-light-300) !important;
}
.nav-button-group {
.nav-link {
&:hover {
background-color: $light-300 !important;
background-color: var(--pgn-color-light-300) !important;
}
}
.nav-link.active,
.show>.nav-link {
background-color: $primary-500 !important;
background-color: var(--pgn-color-primary-500) !important;
}
}
.course-tabs-navigation {
.nav a {
&:hover {
background-color: $light-300 !important;;
background-color: var(--pgn-color-light-300) !important;;
}
}
}
.btn-tertiary:disabled {
color: $gray-700 !important;
color: var(--pgn-color-gray-700) !important;
background-color: transparent !important;
}
@@ -535,14 +535,14 @@ code {
.post-preview,
.discussion-comments {
blockquote {
border-left: 2px solid $gray-200;
border-left: 2px solid var(--pgn-color-gray-200);
margin-left: 1.5rem;
padding-left: 1rem;
}
}
.add-comment-btn {
border: 1px solid $light-300 !important;
border: 1px solid var(--pgn-color-light-300) !important;
}
.icon-size-24 {
@@ -588,7 +588,7 @@ code {
}
th, td {
border: 1px dashed $gray-200;
border: 1px dashed var(--pgn-color-gray-200);
padding: 0.4rem;
white-space: nowrap;
}

View File

@@ -1,12 +1,13 @@
# Footer Slot
### Slot ID: `footer_slot`
### Slot ID: `org.openedx.frontend.layout.footer.v1`
## Description
### Slot ID Aliases
* `footer_slot`
This slot is used to replace/modify/hide the footer.
The implementation of the `FooterSlot` component lives in [the `frontend-slot-footer` repository](https://github.com/openedx/frontend-slot-footer/).
The implementation of the `FooterSlot` component lives in [the `frontend-component-footer` repository](https://github.com/openedx/frontend-component-footer/).
## Example
@@ -23,7 +24,7 @@ import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-frame
const config = {
pluginSlots: {
footer_slot: {
'org.openedx.frontend.layout.footer.v1': {
plugins: [
{
// Hide the default footer

View File

@@ -1,3 +1,3 @@
# `frontend-app-discussions` Plugin Slots
* [`footer_slot`](./FooterSlot/)
* [`org.openedx.frontend.layout.footer.v1`](./FooterSlot/)