feat: standardize slot ids (#1854)
This commit is contained in:
2
package-lock.json
generated
2
package-lock.json
generated
@@ -37,7 +37,7 @@
|
||||
"@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.3.3",
|
||||
"@openedx/frontend-plugin-framework": "^1.6.0",
|
||||
"@openedx/frontend-plugin-framework": "^1.7.0",
|
||||
"@openedx/frontend-slot-footer": "^1.2.0",
|
||||
"@openedx/paragon": "^22.16.0",
|
||||
"@redux-devtools/extension": "^3.3.0",
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
"@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.3.3",
|
||||
"@openedx/frontend-plugin-framework": "^1.6.0",
|
||||
"@openedx/frontend-plugin-framework": "^1.7.0",
|
||||
"@openedx/frontend-slot-footer": "^1.2.0",
|
||||
"@openedx/paragon": "^22.16.0",
|
||||
"@redux-devtools/extension": "^3.3.0",
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
TransitionReplace,
|
||||
} from '@openedx/paragon';
|
||||
import { ChevronLeft, ChevronRight, Close } from '@openedx/paragon/icons';
|
||||
import { PluginSlot } from '@openedx/frontend-plugin-framework';
|
||||
import { AdditionalTranslationsComponentSlot } from '../../../plugin-slots/AdditionalTranslationsComponentSlot';
|
||||
import OrderTranscriptForm from './OrderTranscriptForm';
|
||||
import messages from './messages';
|
||||
import {
|
||||
@@ -116,14 +116,12 @@ const TranscriptSettings = ({
|
||||
)}
|
||||
<TransitionReplace>
|
||||
<div data-testid="translations-component">
|
||||
<PluginSlot
|
||||
id="additonal_translations_component_slot"
|
||||
pluginProps={{
|
||||
setIsAiTranslations,
|
||||
closeTranscriptSettings,
|
||||
courseId,
|
||||
additionalProps: { transcriptType, isAiTranslationsEnabled },
|
||||
}}
|
||||
<AdditionalTranslationsComponentSlot
|
||||
setIsAiTranslations={setIsAiTranslations}
|
||||
closeTranscriptSettings={closeTranscriptSettings}
|
||||
courseId={courseId}
|
||||
transcriptType={transcriptType}
|
||||
isAiTranslationsEnabled={isAiTranslationsEnabled}
|
||||
/>
|
||||
</div>
|
||||
</TransitionReplace>
|
||||
|
||||
@@ -20,6 +20,8 @@ import { RequestStatus } from '../data/constants';
|
||||
import SettingsComponent from './SettingsComponent';
|
||||
import PermissionDeniedAlert from '../generic/PermissionDeniedAlert';
|
||||
import getPageHeadTitle from '../generic/utils';
|
||||
import { AdditionalCoursePluginSlot } from '../plugin-slots/AdditionalCoursePluginSlot';
|
||||
import { AdditionalCourseContentPluginSlot } from '../plugin-slots/AdditionalCourseContentPluginSlot';
|
||||
|
||||
const PagesAndResources = ({ courseId }) => {
|
||||
const intl = useIntl();
|
||||
@@ -90,7 +92,7 @@ const PagesAndResources = ({ courseId }) => {
|
||||
<Route path=":appId/settings" element={<PageWrap><SettingsComponent url={redirectUrl} /></PageWrap>} />
|
||||
</Routes>
|
||||
|
||||
<PageGrid pages={pages} pluginSlotId="additional_course_plugin" courseId={courseId} />
|
||||
<PageGrid pages={pages} pluginSlotComponent={AdditionalCoursePluginSlot} courseId={courseId} />
|
||||
{
|
||||
(contentPermissionsPages.length > 0 || hasAdditionalCoursePlugin)
|
||||
&& (
|
||||
@@ -98,7 +100,7 @@ const PagesAndResources = ({ courseId }) => {
|
||||
<div className="d-flex justify-content-between my-4 my-md-5 align-items-center">
|
||||
<h3 className="m-0">{intl.formatMessage(messages.contentPermissions)}</h3>
|
||||
</div>
|
||||
<PageGrid pages={contentPermissionsPages} pluginSlotId="additional_course_content_plugin" />
|
||||
<PageGrid pages={contentPermissionsPages} pluginSlotComponent={AdditionalCourseContentPluginSlot} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { CardGrid } from '@openedx/paragon';
|
||||
import { PluginSlot } from '@openedx/frontend-plugin-framework';
|
||||
import PageCard, { CoursePageShape } from './PageCard';
|
||||
|
||||
const PageGrid = ({ pages, pluginSlotId, courseId }) => (
|
||||
const PageGrid = ({ pages, pluginSlotComponent, courseId }) => (
|
||||
<CardGrid columnSizes={{
|
||||
xs: 12,
|
||||
sm: 6,
|
||||
@@ -15,18 +14,18 @@ const PageGrid = ({ pages, pluginSlotId, courseId }) => (
|
||||
{pages.map((page) => (
|
||||
<PageCard page={page} key={page.id} courseId={courseId} />
|
||||
))}
|
||||
{pluginSlotId && <PluginSlot id={pluginSlotId} />}
|
||||
{pluginSlotComponent}
|
||||
</CardGrid>
|
||||
);
|
||||
|
||||
PageGrid.defaultProps = {
|
||||
pluginSlotId: null,
|
||||
pluginSlotComponent: null,
|
||||
courseId: null,
|
||||
};
|
||||
|
||||
PageGrid.propTypes = {
|
||||
pages: PropTypes.arrayOf(CoursePageShape.isRequired).isRequired,
|
||||
pluginSlotId: PropTypes.string,
|
||||
pluginSlotComponent: PropTypes.element,
|
||||
courseId: PropTypes.string,
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# AdditionalCourseContentPluginSlot
|
||||
|
||||
### Slot ID: `org.openedx.frontend.authoring.additional_course_content_plugin.v1`
|
||||
|
||||
### Slot ID Aliases
|
||||
* `additional_course_content_plugin`
|
||||
@@ -0,0 +1,12 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`AdditionalCourseContentPluginSlot renders 1`] = `
|
||||
<PluginSlot
|
||||
id="org.openedx.frontend.authoring.additional_course_content_plugin.v1"
|
||||
idAliases={
|
||||
[
|
||||
"additional_course_content_plugin",
|
||||
]
|
||||
}
|
||||
/>
|
||||
`;
|
||||
@@ -0,0 +1,15 @@
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
import { AdditionalCourseContentPluginSlot } from '.';
|
||||
|
||||
jest.mock('@openedx/frontend-plugin-framework', () => ({
|
||||
PluginSlot: 'PluginSlot',
|
||||
}));
|
||||
|
||||
describe('AdditionalCourseContentPluginSlot', () => {
|
||||
beforeEach(() => jest.resetAllMocks());
|
||||
|
||||
it('renders', () => {
|
||||
const wrapper = shallow(<AdditionalCourseContentPluginSlot />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import { PluginSlot } from '@openedx/frontend-plugin-framework/dist';
|
||||
import React from 'react';
|
||||
|
||||
export const AdditionalCourseContentPluginSlot = () => (
|
||||
<PluginSlot
|
||||
id="org.openedx.frontend.authoring.additional_course_content_plugin.v1"
|
||||
idAliases={['additional_course_content_plugin']}
|
||||
/>
|
||||
);
|
||||
6
src/plugin-slots/AdditionalCoursePluginSlot/README.md
Normal file
6
src/plugin-slots/AdditionalCoursePluginSlot/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# AdditionalCoursePluginSlot
|
||||
|
||||
### Slot ID: `org.openedx.frontend.authoring.additional_course_plugin.v1`
|
||||
|
||||
### Slot ID Aliases
|
||||
* `additional_course_plugin`
|
||||
@@ -0,0 +1,12 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`AdditionalCoursePluginSlot renders 1`] = `
|
||||
<PluginSlot
|
||||
id="org.openedx.frontend.authoring.additional_course_plugin.v1"
|
||||
idAliases={
|
||||
[
|
||||
"additional_course_plugin",
|
||||
]
|
||||
}
|
||||
/>
|
||||
`;
|
||||
15
src/plugin-slots/AdditionalCoursePluginSlot/index.test.jsx
Normal file
15
src/plugin-slots/AdditionalCoursePluginSlot/index.test.jsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
import { AdditionalCoursePluginSlot } from '.';
|
||||
|
||||
jest.mock('@openedx/frontend-plugin-framework', () => ({
|
||||
PluginSlot: 'PluginSlot',
|
||||
}));
|
||||
|
||||
describe('AdditionalCoursePluginSlot', () => {
|
||||
beforeEach(() => jest.resetAllMocks());
|
||||
|
||||
it('renders', () => {
|
||||
const wrapper = shallow(<AdditionalCoursePluginSlot />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
9
src/plugin-slots/AdditionalCoursePluginSlot/index.tsx
Normal file
9
src/plugin-slots/AdditionalCoursePluginSlot/index.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import { PluginSlot } from '@openedx/frontend-plugin-framework/dist';
|
||||
import React from 'react';
|
||||
|
||||
export const AdditionalCoursePluginSlot = () => (
|
||||
<PluginSlot
|
||||
id="org.openedx.frontend.authoring.additional_course_plugin.v1"
|
||||
idAliases={['additional_course_plugin']}
|
||||
/>
|
||||
);
|
||||
@@ -0,0 +1,15 @@
|
||||
# AdditionalTranslationsComponentSlot
|
||||
|
||||
### Slot ID: `org.openedx.frontend.authoring.video_transcript_additional_translations_component.v1`
|
||||
|
||||
### Slot ID Aliases
|
||||
* `additonal_translations_component_slot` (original misspelling)
|
||||
* `additional_translations_component_slot`
|
||||
|
||||
### Plugin Props:
|
||||
* `setIsAiTranslations` - Function (React SetState)
|
||||
* `closeTranscriptSettings` - Function (Paragon useToggle)
|
||||
* `courseId` - String
|
||||
* `additionalProps` - Object
|
||||
* `transcriptType` - String
|
||||
* `isAiTranslationsEnabled` - Boolean
|
||||
@@ -0,0 +1,32 @@
|
||||
import { PluginSlot } from '@openedx/frontend-plugin-framework/dist';
|
||||
import React from 'react';
|
||||
|
||||
export const AdditionalTranslationsComponentSlot = ({
|
||||
setIsAiTranslations,
|
||||
closeTranscriptSettings,
|
||||
courseId,
|
||||
transcriptType,
|
||||
isAiTranslationsEnabled,
|
||||
}: AdditionalTranslationsComponentSlotProps) => (
|
||||
<PluginSlot
|
||||
id="org.openedx.frontend.authoring.video_transcript_additional_translations_component.v1"
|
||||
idAliases={[
|
||||
'additonal_translations_component_slot', // original misspelling
|
||||
'additional_translations_component_slot',
|
||||
]}
|
||||
pluginProps={{
|
||||
setIsAiTranslations,
|
||||
closeTranscriptSettings,
|
||||
courseId,
|
||||
additionalProps: { transcriptType, isAiTranslationsEnabled },
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
interface AdditionalTranslationsComponentSlotProps {
|
||||
setIsAiTranslations: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
closeTranscriptSettings: () => void;
|
||||
courseId: string;
|
||||
transcriptType: string;
|
||||
isAiTranslationsEnabled: boolean;
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
# CourseAuthoringOutlineSidebarSlot
|
||||
|
||||
### Slot ID: `course_authoring_outline_sidebar_slot`
|
||||
### Slot ID: `org.openedx.frontend.authoring.course_outline_sidebar.v1`
|
||||
|
||||
### Slot ID Aliases
|
||||
* `course_authoring_outline_sidebar_slot`
|
||||
|
||||
### Plugin Props:
|
||||
|
||||
@@ -24,7 +27,7 @@ import { PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';
|
||||
|
||||
const config = {
|
||||
pluginSlots: {
|
||||
course_authoring_outline_sidebar_slot: {
|
||||
'org.openedx.frontend.authoring.course_outline_sidebar.v1': {
|
||||
keepDefault: true,
|
||||
plugins: [
|
||||
{
|
||||
|
||||
@@ -8,7 +8,8 @@ export const CourseAuthoringOutlineSidebarSlot = ({
|
||||
sections,
|
||||
}: CourseAuthoringOutlineSidebarSlotProps) => (
|
||||
<PluginSlot
|
||||
id="course_authoring_outline_sidebar_slot"
|
||||
id="org.openedx.frontend.authoring.course_outline_sidebar.v1"
|
||||
idAliases={['course_authoring_outline_sidebar_slot']}
|
||||
pluginProps={{
|
||||
courseId,
|
||||
courseName,
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# CourseAuthoringUnitSidebarSlot
|
||||
|
||||
### Slot ID: `course_authoring_unit_sidebar_slot`
|
||||
### Slot ID: `org.openedx.frontend.authoring.course_unit_sidebar.v1`
|
||||
|
||||
### Slot ID Aliases
|
||||
* `course_authoring_unit_sidebar_slot`
|
||||
|
||||
### Plugin Props:
|
||||
|
||||
@@ -25,7 +28,7 @@ import { PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';
|
||||
|
||||
const config = {
|
||||
pluginSlots: {
|
||||
course_authoring_unit_sidebar_slot: {
|
||||
'org.openedx.frontend.authoring.course_unit_sidebar.v1': {
|
||||
keepDefault: true,
|
||||
plugins: [
|
||||
{
|
||||
@@ -63,7 +66,7 @@ const ProblemBlocks = ({unitTitle, xBlocks}) => (
|
||||
|
||||
const config = {
|
||||
pluginSlots: {
|
||||
course_authoring_unit_sidebar_slot: {
|
||||
'org.openedx.frontend.authoring.course_unit_sidebar.v1': {
|
||||
keepDefault: true,
|
||||
plugins: [
|
||||
{
|
||||
|
||||
@@ -14,7 +14,8 @@ export const CourseAuthoringUnitSidebarSlot = (
|
||||
}: CourseAuthoringUnitSidebarSlotProps,
|
||||
) => (
|
||||
<PluginSlot
|
||||
id="course_authoring_unit_sidebar_slot"
|
||||
id="org.openedx.frontend.authoring.course_unit_sidebar.v1"
|
||||
idAliases={['course_authoring_unit_sidebar_slot']}
|
||||
pluginProps={{
|
||||
blockId, courseId, unitTitle, xBlocks,
|
||||
}}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# CourseOutlineHeaderActionsSlot
|
||||
|
||||
### Slot ID: `course_outline_header_actions_slot`
|
||||
### Slot ID: `org.openedx.frontend.authoring.course_outline_header_actions.v1`
|
||||
|
||||
### Slot ID Aliases
|
||||
* `course_outline_header_actions_slot`
|
||||
|
||||
### Plugin Props:
|
||||
|
||||
* `isReIndexShow` - Boolean.
|
||||
@@ -33,7 +37,7 @@ const MyButton = () => (
|
||||
|
||||
const config = {
|
||||
pluginSlots: {
|
||||
course_outline_header_actions_slot: {
|
||||
'org.openedx.frontend.authoring.course_outline_header_actions.v1': {
|
||||
keepDefault: true,
|
||||
plugins: [
|
||||
{
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
|
||||
exports[`CourseOutlineHeaderActionsSlot pluginProps are set correctly 1`] = `
|
||||
<PluginSlot
|
||||
id="course_outline_header_actions_slot"
|
||||
id="org.openedx.frontend.authoring.course_outline_header_actions.v1"
|
||||
idAliases={
|
||||
[
|
||||
"course_outline_header_actions_slot",
|
||||
]
|
||||
}
|
||||
pluginProps={
|
||||
{
|
||||
"courseActions": {
|
||||
|
||||
@@ -15,7 +15,8 @@ const CourseOutlineHeaderActionsSlot = ({
|
||||
sections,
|
||||
}) => (
|
||||
<PluginSlot
|
||||
id="course_outline_header_actions_slot"
|
||||
id="org.openedx.frontend.authoring.course_outline_header_actions.v1"
|
||||
idAliases={['course_outline_header_actions_slot']}
|
||||
pluginProps={{
|
||||
isReIndexShow,
|
||||
isSectionsExpanded,
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# CourseOutlineSubsectionCardExtraActionsSlot
|
||||
|
||||
### Slot ID: `course_outline_subsection_card_extra_actions_slot`
|
||||
### Slot ID: `org.openedx.frontend.authoring.course_outline_subsection_card_extra_actions.v1`
|
||||
|
||||
### Slot ID Aliases
|
||||
* `course_outline_subsection_card_extra_actions_slot`
|
||||
|
||||
### Plugin Props:
|
||||
|
||||
* `section` - object
|
||||
@@ -36,7 +40,7 @@ const MyIconButton = () => (
|
||||
|
||||
const config = {
|
||||
pluginSlots: {
|
||||
course_outline_subsection_card_extra_actions_slot: {
|
||||
'org.openedx.frontend.authoring.course_outline_subsection_card_extra_actions.v1': {
|
||||
keepDefault: true,
|
||||
plugins: [
|
||||
{
|
||||
|
||||
@@ -4,7 +4,11 @@ import PropTypes from 'prop-types';
|
||||
import { PluginSlot } from '@openedx/frontend-plugin-framework';
|
||||
|
||||
const CourseOutlineSubsectionCardExtraActionsSlot = ({ subsection, section }) => (
|
||||
<PluginSlot id="course_outline_subsection_card_extra_actions_slot" pluginProps={{ subsection, section }} />
|
||||
<PluginSlot
|
||||
id="org.openedx.frontend.authoring.course_outline_subsection_card_extra_actions.v1"
|
||||
idAliases={['course_outline_subsection_card_extra_actions_slot']}
|
||||
pluginProps={{ subsection, section }}
|
||||
/>
|
||||
);
|
||||
|
||||
CourseOutlineSubsectionCardExtraActionsSlot.propTypes = {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# CourseOutlineUnitCardExtraActionsSlot
|
||||
|
||||
### Slot ID: `course_outline_unit_card_extra_actions_slot`
|
||||
### Slot ID: `org.openedx.frontend.authoring.course_outline_unit_card_extra_actions.v1`
|
||||
|
||||
### Slot ID Aliases
|
||||
* `course_outline_unit_card_extra_actions_slot`
|
||||
|
||||
### Plugin Props:
|
||||
|
||||
* `unit` - object
|
||||
@@ -37,7 +41,7 @@ const MyIconButton = () => (
|
||||
|
||||
const config = {
|
||||
pluginSlots: {
|
||||
course_outline_unit_card_extra_actions_slot: {
|
||||
'org.openedx.frontend.authoring.course_outline_unit_card_extra_actions.v1': {
|
||||
keepDefault: true,
|
||||
plugins: [
|
||||
{
|
||||
|
||||
@@ -4,7 +4,11 @@ import PropTypes from 'prop-types';
|
||||
import { PluginSlot } from '@openedx/frontend-plugin-framework';
|
||||
|
||||
const CourseOutlineUnitCardExtraActionsSlot = ({ unit, subsection, section }) => (
|
||||
<PluginSlot id="course_outline_unit_card_extra_actions_slot" pluginProps={{ unit, subsection, section }} />
|
||||
<PluginSlot
|
||||
id="org.openedx.frontend.authoring.course_outline_unit_card_extra_actions.v1"
|
||||
idAliases={['course_outline_unit_card_extra_actions_slot']}
|
||||
pluginProps={{ unit, subsection, section }}
|
||||
/>
|
||||
);
|
||||
|
||||
CourseOutlineUnitCardExtraActionsSlot.propTypes = {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# CourseUnitHeaderActionsSlot
|
||||
|
||||
### Slot ID: `course_unit_header_actions_slot`
|
||||
### Slot ID: `org.openedx.frontend.authoring.course_unit_header_actions.v1`
|
||||
|
||||
### Slot ID Aliases
|
||||
* `course_unit_header_actions_slot`
|
||||
|
||||
### Plugin Props:
|
||||
|
||||
* `headerNavigationsActions` - Object. See the prop-types definition in the component for details.
|
||||
@@ -31,7 +35,7 @@ const MyButton = () => (
|
||||
|
||||
const config = {
|
||||
pluginSlots: {
|
||||
course_unit_header_actions_slot: {
|
||||
'org.openedx.frontend.authoring.course_unit_header_actions.v1': {
|
||||
keepDefault: true,
|
||||
plugins: [
|
||||
{
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
|
||||
exports[`CourseUnitHeaderActionsSlot pluginProps are set correctly 1`] = `
|
||||
<PluginSlot
|
||||
id="course_unit_header_actions_slot"
|
||||
id="org.openedx.frontend.authoring.course_unit_header_actions.v1"
|
||||
idAliases={
|
||||
[
|
||||
"course_unit_header_actions_slot",
|
||||
]
|
||||
}
|
||||
pluginProps={
|
||||
{
|
||||
"category": "vertical",
|
||||
|
||||
@@ -12,7 +12,8 @@ const CourseUnitHeaderActionsSlot = ({
|
||||
const isUnitVerticalType = category === COURSE_BLOCK_NAMES.vertical.id;
|
||||
return (
|
||||
<PluginSlot
|
||||
id="course_unit_header_actions_slot"
|
||||
id="org.openedx.frontend.authoring.course_unit_header_actions.v1"
|
||||
idAliases={['course_unit_header_actions_slot']}
|
||||
pluginProps={{
|
||||
headerNavigationsActions, category, unitTitle, isUnitVerticalType, verticalBlocks,
|
||||
}}
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
# `frontend-app-authoring` Plugin Slots
|
||||
|
||||
## Course Outline Page
|
||||
|
||||
* [`course_outline_header_actions_slot`](./CourseOutlineHeaderActionsSlot/)
|
||||
* [`course_outline_subsection_card_extra_actions_slot`](./CourseOutlineSubsectionCardExtraActionsSlot)
|
||||
* [`course_outline_unit_card_extra_actions_slot`](./CourseOutlineUnitCardExtraActionsSlot)
|
||||
* [`org.openedx.frontend.authoring.course_outline_header_actions.v1`](./CourseOutlineHeaderActionsSlot/)
|
||||
* [`org.openedx.frontend.authoring.course_outline_sidebar.v1`](./CourseAuthoringOutlineSidebarSlot/)
|
||||
* [`org.openedx.frontend.authoring.course_outline_subsection_card_extra_actions.v1`](./CourseOutlineSubsectionCardExtraActionsSlot)
|
||||
* [`org.openedx.frontend.authoring.course_outline_unit_card_extra_actions.v1`](./CourseOutlineUnitCardExtraActionsSlot)
|
||||
|
||||
## Course Unit page
|
||||
* [`org.openedx.frontend.authoring.course_unit_header_actions.v1`](./CourseUnitHeaderActionsSlot/)
|
||||
* [`org.openedx.frontend.authoring.course_unit_sidebar.v1`](./CourseAuthoringUnitSidebarSlot/)
|
||||
|
||||
* [`course_unit_header_actions_slot`](./CourseUnitHeaderActionsSlot/)
|
||||
## Other Slots
|
||||
* [`org.openedx.frontend.authoring.additional_course_content_plugin.v1`](./AdditionalCourseContentPluginSlot/)
|
||||
* [`org.openedx.frontend.authoring.additional_course_plugin.v1`](./AdditionalCoursePluginSlot/)
|
||||
* [`org.openedx.frontend.authoring.video_transcript_additional_translations_component.v1`](./AdditionalTranslationsComponentSlot/)
|
||||
|
||||
## Footer Slot
|
||||
* [`studio_footer_slot`](./StudioFooterSlot/)
|
||||
|
||||
Reference in New Issue
Block a user