Skip to content

Commit b6bd94c

Browse files
tecoholicfarhaanbukhsh
authored andcommitted
feat: add v2 CourseAuthoringUnitSidebarSlot (#2000)
1 parent c9896a8 commit b6bd94c

File tree

4 files changed

+148
-40
lines changed

4 files changed

+148
-40
lines changed

src/course-unit/CourseUnit.jsx

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import PropTypes from 'prop-types';
33
import { useSelector } from 'react-redux';
44
import { useParams } from 'react-router-dom';
55
import {
6-
Container, Layout, Stack, Button, TransitionReplace,
7-
Alert,
6+
Alert, Container, Layout, Button, TransitionReplace,
87
} from '@openedx/paragon';
98
import { useIntl } from '@edx/frontend-platform/i18n';
109
import {
@@ -27,8 +26,6 @@ import AddComponent from './add-component/AddComponent';
2726
import HeaderTitle from './header-title/HeaderTitle';
2827
import Breadcrumbs from './breadcrumbs/Breadcrumbs';
2928
import Sequence from './course-sequence';
30-
import Sidebar from './sidebar';
31-
import SplitTestSidebarInfo from './sidebar/SplitTestSidebarInfo';
3229
import { useCourseUnit, useLayoutGrid, useScrollToLastPosition } from './hooks';
3330
import messages from './messages';
3431
import { PasteNotificationAlert } from './clipboard';
@@ -244,22 +241,15 @@ const CourseUnit = ({ courseId }) => {
244241
<IframePreviewLibraryXBlockChanges />
245242
</Layout.Element>
246243
<Layout.Element>
247-
<Stack gap={3}>
248-
{isUnitVerticalType && (
249-
<CourseAuthoringUnitSidebarSlot
250-
courseId={courseId}
251-
blockId={blockId}
252-
unitTitle={unitTitle}
253-
xBlocks={courseVerticalChildren.children}
254-
readOnly={readOnly}
255-
/>
256-
)}
257-
{isSplitTestType && (
258-
<Sidebar data-testid="course-split-test-sidebar">
259-
<SplitTestSidebarInfo />
260-
</Sidebar>
261-
)}
262-
</Stack>
244+
<CourseAuthoringUnitSidebarSlot
245+
courseId={courseId}
246+
blockId={blockId}
247+
unitTitle={unitTitle}
248+
xBlocks={courseVerticalChildren.children}
249+
readOnly={readOnly}
250+
isUnitVerticalType={isUnitVerticalType}
251+
isSplitTestType={isSplitTestType}
252+
/>
263253
</Layout.Element>
264254
</Layout>
265255
</section>

src/plugin-slots/CourseAuthoringUnitSidebarSlot/README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
# CourseAuthoringUnitSidebarSlot
22

3-
### Slot ID: `org.openedx.frontend.authoring.course_unit_sidebar.v1`
3+
### Slot ID: `org.openedx.frontend.authoring.course_unit_sidebar.v2`
44

5-
### Slot ID Aliases
6-
* `course_authoring_unit_sidebar_slot`
5+
### Previous Version: [`org.openedx.frontend.authoring.course_unit_sidebar.v1`](./README.v1.md)
76

87
### Plugin Props:
98

@@ -12,6 +11,8 @@
1211
* `unitTitle` - String. The name of the current unit being viewed / edited.
1312
* `xBlocks` - Array of Objects. List of XBlocks in the Unit. Object structure defined in `index.tsx`.
1413
* `readOnly` - Boolean. True if the user should not be able to edit the contents of the unit.
14+
* `isUnitVerticalType` - Boolean. If the unit category is `vertical`.
15+
* `isSplitTestType` - Boolean. If the unit category is `split_test`.
1516

1617
## Description
1718

@@ -29,7 +30,7 @@ import { PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';
2930

3031
const config = {
3132
pluginSlots: {
32-
'org.openedx.frontend.authoring.course_unit_sidebar.v1': {
33+
'org.openedx.frontend.authoring.course_unit_sidebar.v2': {
3334
keepDefault: true,
3435
plugins: [
3536
{
@@ -63,11 +64,11 @@ const ProblemBlocks = ({unitTitle, xBlocks}) => (
6364
}
6465
</ul>
6566
</>
66-
);
67+
);
6768

6869
const config = {
6970
pluginSlots: {
70-
'org.openedx.frontend.authoring.course_unit_sidebar.v1': {
71+
'org.openedx.frontend.authoring.course_unit_sidebar.v2': {
7172
keepDefault: true,
7273
plugins: [
7374
{
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# CourseAuthoringUnitSidebarSlot
2+
3+
### Slot ID: `org.openedx.frontend.authoring.course_unit_sidebar.v1`
4+
5+
### Slot ID Aliases: `course_authoring_unit_sidebar_slot`
6+
7+
### Plugin Props:
8+
9+
* `courseId` - String.
10+
* `blockId` - String. The usage id of the current unit being viewed / edited.
11+
* `unitTitle` - String. The name of the current unit being viewed / edited.
12+
* `xBlocks` - Array of Objects. List of XBlocks in the Unit. Object structure defined in `index.tsx`.
13+
* `readOnly` - Boolean. True if the user should not be able to edit the contents of the unit.
14+
15+
### Description
16+
17+
The slot wraps the sidebar that is displayed on the unit editor page. It can
18+
be used to add additional sidebar components or modify the existing sidebar.
19+
20+
> [!IMPORTANT]
21+
> This document describes an older version `v1` of the `CourseAuthoringUnitSidebarSlot`.
22+
> It is recommended to use the `org.openedx.frontend.authoring.course_unit_sidebar.v2` slot ID for new plugins.
23+
24+
The `v1` slot has the following limitations compared to the `v2` version:
25+
* It renders conditionally based on the `isUnitVerticalType` prop, which means the plugins won't be rendered in other scenarios like unit with library blocks.
26+
* It does **not** wrap the `SplitTestSidebarInfo` component. So it can't be hidden from the sidebar by overriding the components in the slot.
27+
* As it is not the primary child component of the sidebar, CSS styling for inserted components face limitations, such as an inability to be `sticky` or achieve 100% height.
28+
29+
## Example 1
30+
31+
![Screenshot of the unit sidebar surrounded by border](./images/unit_sidebar_with_border.png)
32+
33+
The following example configuration surrounds the sidebar in a border as shown above.
34+
35+
```js
36+
import { PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';
37+
38+
const config = {
39+
pluginSlots: {
40+
'org.openedx.frontend.authoring.course_unit_sidebar.v1': {
41+
keepDefault: true,
42+
plugins: [
43+
{
44+
op: PLUGIN_OPERATIONS.Wrap,
45+
widgetId: 'default_contents',
46+
wrapper: ({ component }) => (
47+
<div style={{ border: 'thick dashed red' }}>{component}</div>
48+
),
49+
},
50+
],
51+
},
52+
}
53+
};
54+
export default config;
55+
```
56+
57+
## Example 2
58+
59+
![Screenshot of the unit sidebar with an extra component listing all the problem blocks](./images/unit_sidebar_with_problem_blocks_list.png)
60+
61+
```js
62+
import { PLUGIN_OPERATIONS, DIRECT_PLUGIN } from '@openedx/frontend-plugin-framework';
63+
64+
const ProblemBlocks = ({unitTitle, xBlocks}) => (
65+
<>
66+
<h4 className="h4">{unitTitle}: Problem Blocks</h4>
67+
<ul>
68+
{xBlocks
69+
.filter(block => block.blockType === "problem")
70+
.map(block => <li key={block.id}>{block.displayName}</li>)
71+
}
72+
</ul>
73+
</>
74+
);
75+
76+
const config = {
77+
pluginSlots: {
78+
'org.openedx.frontend.authoring.course_unit_sidebar.v1': {
79+
keepDefault: true,
80+
plugins: [
81+
{
82+
op: PLUGIN_OPERATIONS.Insert,
83+
widget:{
84+
id: 'problem-blocks-list',
85+
priority: 1,
86+
type: DIRECT_PLUGIN,
87+
RenderWidget: ProblemBlocks,
88+
}
89+
},
90+
],
91+
},
92+
}
93+
};
94+
export default config;
95+
```
Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { getConfig } from '@edx/frontend-platform';
22
import { PluginSlot } from '@openedx/frontend-plugin-framework/dist';
3+
import { Stack } from '@openedx/paragon';
34
import TagsSidebarControls from '../../content-tags-drawer/tags-sidebar-controls';
45
import Sidebar from '../../course-unit/sidebar';
56
import LocationInfo from '../../course-unit/sidebar/LocationInfo';
67
import PublishControls from '../../course-unit/sidebar/PublishControls';
8+
import SplitTestSidebarInfo from '../../course-unit/sidebar/SplitTestSidebarInfo';
79

810
export const CourseAuthoringUnitSidebarSlot = (
911
{
@@ -12,26 +14,44 @@ export const CourseAuthoringUnitSidebarSlot = (
1214
unitTitle,
1315
xBlocks,
1416
readOnly,
17+
isUnitVerticalType,
18+
isSplitTestType,
1519
}: CourseAuthoringUnitSidebarSlotProps,
1620
) => (
1721
<PluginSlot
18-
id="org.openedx.frontend.authoring.course_unit_sidebar.v1"
19-
idAliases={['course_authoring_unit_sidebar_slot']}
22+
id="org.openedx.frontend.authoring.course_unit_sidebar.v2"
2023
pluginProps={{
21-
blockId, courseId, unitTitle, xBlocks, readOnly,
24+
blockId, courseId, unitTitle, xBlocks, readOnly, isUnitVerticalType, isSplitTestType,
2225
}}
2326
>
24-
<Sidebar data-testid="course-unit-sidebar">
25-
<PublishControls blockId={blockId} />
26-
</Sidebar>
27-
{getConfig().ENABLE_TAGGING_TAXONOMY_PAGES === 'true' && (
28-
<Sidebar className="tags-sidebar">
29-
<TagsSidebarControls readOnly={readOnly} />
30-
</Sidebar>
31-
)}
32-
<Sidebar data-testid="course-unit-location-sidebar">
33-
<LocationInfo />
34-
</Sidebar>
27+
<Stack gap={3}>
28+
{isUnitVerticalType && (
29+
<PluginSlot
30+
id="org.openedx.frontend.authoring.course_unit_sidebar.v1"
31+
idAliases={['course_authoring_unit_sidebar_slot']}
32+
pluginProps={{
33+
blockId, courseId, unitTitle, xBlocks, readOnly,
34+
}}
35+
>
36+
<Sidebar data-testid="course-unit-sidebar">
37+
<PublishControls blockId={blockId} />
38+
</Sidebar>
39+
{getConfig().ENABLE_TAGGING_TAXONOMY_PAGES === 'true' && (
40+
<Sidebar className="tags-sidebar">
41+
<TagsSidebarControls readOnly={readOnly} />
42+
</Sidebar>
43+
)}
44+
<Sidebar data-testid="course-unit-location-sidebar">
45+
<LocationInfo />
46+
</Sidebar>
47+
</PluginSlot>
48+
)}
49+
{isSplitTestType && (
50+
<Sidebar data-testid="course-split-test-sidebar">
51+
<SplitTestSidebarInfo />
52+
</Sidebar>
53+
)}
54+
</Stack>
3555
</PluginSlot>
3656
);
3757

@@ -47,4 +67,6 @@ interface CourseAuthoringUnitSidebarSlotProps {
4767
unitTitle: string;
4868
xBlocks: XBlock[];
4969
readOnly: boolean;
70+
isUnitVerticalType: boolean;
71+
isSplitTestType: boolean;
5072
}

0 commit comments

Comments
 (0)