Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
490da867df | ||
|
|
fd723e6063 | ||
|
|
664ca3e78f | ||
|
|
18a8a76105 | ||
|
|
0ad89f88a1 | ||
|
|
b0391866a3 | ||
|
|
3a9e3f8fba | ||
|
|
b2c55a09e5 | ||
|
|
6795147255 |
@@ -95,9 +95,9 @@ This library has the following exports:
|
||||
|
||||
Plugin
|
||||
======
|
||||
The footer can be replaced using using `Frontend Plugin Framework <https://github.com/openedx/frontend-plugin-framework>`_.
|
||||
The footer can be replaced or modified using `Frontend Plugin Framework <https://github.com/openedx/frontend-plugin-framework>`_.
|
||||
|
||||
Information on how to utilize the ``FooterSlot`` component to do so is available in the `frontend-slot-footer repository <https://github.com/openedx/frontend-slot-footer/>`_.
|
||||
Information on how to replace or modify the footer is available `here </src/plugin-slots>`_.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
69
package-lock.json
generated
69
package-lock.json
generated
@@ -14,7 +14,7 @@
|
||||
"@fortawesome/free-regular-svg-icons": "6.7.2",
|
||||
"@fortawesome/free-solid-svg-icons": "6.7.2",
|
||||
"@fortawesome/react-fontawesome": "0.2.2",
|
||||
"@openedx/frontend-plugin-framework": "^1.5.0",
|
||||
"@openedx/frontend-plugin-framework": "^1.7.0",
|
||||
"classnames": "^2.5.1",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"lodash": "^4.17.21",
|
||||
@@ -2262,16 +2262,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-platform": {
|
||||
"version": "8.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-8.3.4.tgz",
|
||||
"integrity": "sha512-V3XtTo3KP8QSmId+Vvi4+qzpOVkxvTMNA6jH/i3Bfz+/jHjHBRnmp/Cc2pjTxiTgGNoKX4D1twiZkOBO+kWw1Q==",
|
||||
"version": "8.3.6",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-8.3.6.tgz",
|
||||
"integrity": "sha512-3NzUXW1oGWIk6RjtKzCUSNyR9zG2jpl2aiiT9BTvHwN3yFhk0+JSJE86jF+dZg3ZOFKWo2OG07Lguz/cihOQkw==",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@cospired/i18n-iso-languages": "4.2.0",
|
||||
"@formatjs/intl-pluralrules": "4.3.3",
|
||||
"@formatjs/intl-relativetimeformat": "10.0.1",
|
||||
"axios": "1.8.4",
|
||||
"axios-cache-interceptor": "1.6.2",
|
||||
"axios": "1.9.0",
|
||||
"axios-cache-interceptor": "1.8.0",
|
||||
"form-urlencoded": "4.1.4",
|
||||
"glob": "7.2.3",
|
||||
"history": "4.10.1",
|
||||
@@ -3896,9 +3896,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build": {
|
||||
"version": "14.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/frontend-build/-/frontend-build-14.4.2.tgz",
|
||||
"integrity": "sha512-RWAsaYq88cGlqO4eDDo/ylY6dJsbeBsI+4LxmKPrW4MPh0rIFZILvH+X3z/t9SVTlGTx4UkUQV9LXPGLKdcA1g==",
|
||||
"version": "14.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/frontend-build/-/frontend-build-14.6.0.tgz",
|
||||
"integrity": "sha512-lQn/IYC2xZxmYtm9AsrEXm7o3Ei0voZNTKFDGiBbZARsh27b2/e8hx3ToJ4B3rwxnSHLNYbxVYqAWSiAXG06dw==",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@babel/cli": "7.24.8",
|
||||
@@ -4048,9 +4048,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/frontend-plugin-framework/-/frontend-plugin-framework-1.6.0.tgz",
|
||||
"integrity": "sha512-zgP+/hs/cvcPmFOgVm2xt/qgX1nheNsfipzCO7I3bON4hHyOhmOyzwFZJ7pz7GzCJwKlMVguh3HcJgf4p/BPKQ==",
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/frontend-plugin-framework/-/frontend-plugin-framework-1.7.0.tgz",
|
||||
"integrity": "sha512-8tGkuHvtzhbqb9dU4sXUtR0K44+Hjh1uGR6DvhZAt9wSKQC1v4RBk34ef8DFzQhoNQa/Jtn6BJuta4Un6MmHmw==",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
|
||||
@@ -4114,9 +4114,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/paragon": {
|
||||
"version": "23.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/paragon/-/paragon-23.4.3.tgz",
|
||||
"integrity": "sha512-twzFgkVZBZKDUhepqvdH1er+0uQSBGs/r1TDIGmN/zNjmc87g7RMbeDWF+j96eOaiTet9Wcv4JHoB3zE6VycFQ==",
|
||||
"version": "23.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/paragon/-/paragon-23.5.1.tgz",
|
||||
"integrity": "sha512-oDPKmndZLYrf2mwwATYYxv1HjUf3Tflr0TeVCfoXNc4kiVGIKI1Zblm9NARSgvUL4Pzn7xYEC0h9tWH0/+cGpw==",
|
||||
"license": "Apache-2.0",
|
||||
"workspaces": [
|
||||
"example",
|
||||
@@ -7375,9 +7375,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.8.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz",
|
||||
"integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz",
|
||||
"integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
@@ -7386,9 +7386,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/axios-cache-interceptor": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/axios-cache-interceptor/-/axios-cache-interceptor-1.6.2.tgz",
|
||||
"integrity": "sha512-YLbAODIHZZIcD4b3WYFVQOa5W2TY/WnJ6sBHqAg6Z+hx+RVj8/OcjQyRopO6awn7/kOkGL5X9TP16AucnlJ/lw==",
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/axios-cache-interceptor/-/axios-cache-interceptor-1.8.0.tgz",
|
||||
"integrity": "sha512-cTNnPGJyQkxnWp0EWvE3NRvgURU5cWw/Qx3dIhXyHSM4Ip0c7EEe0I3an0Jwa549m1CAOg57ibj27YRNLmQCcg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cache-parser": "1.2.5",
|
||||
@@ -26112,9 +26112,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ts-jest": {
|
||||
"version": "29.2.6",
|
||||
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.6.tgz",
|
||||
"integrity": "sha512-yTNZVZqc8lSixm+QGVFcPe6+yj7+TWZwIesuOWvfcn4B9bz5x4NDzVCQQjOs7Hfouu36aEqfEbo9Qpo+gq8dDg==",
|
||||
"version": "29.3.4",
|
||||
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.3.4.tgz",
|
||||
"integrity": "sha512-Iqbrm8IXOmV+ggWHOTEbjwyCf2xZlUMv5npExksXohL+tk8va4Fjhb+X2+Rt9NBmgO7bJ8WpnMLOwih/DnMlFA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bs-logger": "^0.2.6",
|
||||
@@ -26124,7 +26124,8 @@
|
||||
"json5": "^2.2.3",
|
||||
"lodash.memoize": "^4.1.2",
|
||||
"make-error": "^1.3.6",
|
||||
"semver": "^7.7.1",
|
||||
"semver": "^7.7.2",
|
||||
"type-fest": "^4.41.0",
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
"bin": {
|
||||
@@ -26160,9 +26161,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ts-jest/node_modules/semver": {
|
||||
"version": "7.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
||||
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
@@ -26171,6 +26172,18 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-jest/node_modules/type-fest": {
|
||||
"version": "4.41.0",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz",
|
||||
"integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==",
|
||||
"license": "(MIT OR CC0-1.0)",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-jest/node_modules/yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"build": "make build",
|
||||
"i18n_extract": "fedx-scripts formatjs extract",
|
||||
"lint": "fedx-scripts eslint --ext .js --ext .jsx .",
|
||||
"lint:fix": "fedx-scripts eslint --fix --ext .js --ext .jsx .",
|
||||
"snapshot": "fedx-scripts jest --updateSnapshot",
|
||||
"start": "fedx-scripts webpack-dev-server --progress",
|
||||
"start:with-theme": "paragon install-theme && npm start && npm install",
|
||||
@@ -55,7 +56,7 @@
|
||||
"@fortawesome/free-regular-svg-icons": "6.7.2",
|
||||
"@fortawesome/free-solid-svg-icons": "6.7.2",
|
||||
"@fortawesome/react-fontawesome": "0.2.2",
|
||||
"@openedx/frontend-plugin-framework": "^1.5.0",
|
||||
"@openedx/frontend-plugin-framework": "^1.7.0",
|
||||
"classnames": "^2.5.1",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"lodash": "^4.17.21",
|
||||
|
||||
@@ -7,6 +7,7 @@ import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { AppContext } from '@edx/frontend-platform/react';
|
||||
|
||||
import Footer from './Footer';
|
||||
import FooterSlot from '../plugin-slots/FooterSlot';
|
||||
|
||||
const FooterWithContext = ({ locale = 'es' }) => {
|
||||
const contextValue = useMemo(() => ({
|
||||
@@ -22,7 +23,7 @@ const FooterWithContext = ({ locale = 'es' }) => {
|
||||
<AppContext.Provider
|
||||
value={contextValue}
|
||||
>
|
||||
<Footer />
|
||||
<FooterSlot />
|
||||
</AppContext.Provider>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
@@ -5,7 +5,7 @@ import userEvent from '@testing-library/user-event';
|
||||
import '@testing-library/jest-dom/extend-expect';
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { AppContext } from '@edx/frontend-platform/react';
|
||||
import StudioFooter from './StudioFooter';
|
||||
import StudioFooterSlot from '../../plugin-slots/StudioFooterSlot';
|
||||
import messages from './messages';
|
||||
|
||||
const config = {
|
||||
@@ -36,7 +36,7 @@ const Component = ({ updateVariable }) => {
|
||||
return (
|
||||
<IntlProvider locale="en">
|
||||
<AppContext.Provider value={contextValue}>
|
||||
<StudioFooter />
|
||||
<StudioFooterSlot />
|
||||
</AppContext.Provider>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import Footer, { EVENT_NAMES } from './components/Footer';
|
||||
import messages from './i18n/index';
|
||||
import StudioFooter from './components/studio-footer';
|
||||
import FooterSlot from './plugin-slots/FooterSlot';
|
||||
import StudioFooterSlot from './plugin-slots/StudioFooterSlot';
|
||||
|
||||
export default Footer;
|
||||
export {
|
||||
messages, EVENT_NAMES, StudioFooter,
|
||||
messages, EVENT_NAMES, StudioFooter, FooterSlot, StudioFooterSlot,
|
||||
};
|
||||
|
||||
51
src/plugin-slots/FooterSlot/README.md
Normal file
51
src/plugin-slots/FooterSlot/README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# FooterSlot
|
||||
|
||||
### Slot ID: `org.openedx.frontend.layout.footer.v1`
|
||||
|
||||
### Slot ID Aliases
|
||||
* `footer_slot`
|
||||
|
||||
## Description
|
||||
|
||||
This slot is used to repace/modify/hide the entire footer.
|
||||
|
||||
## Example
|
||||
|
||||
The following `env.config.jsx` will replace the default footer.
|
||||
|
||||

|
||||
|
||||
with a simple custom footer
|
||||
|
||||

|
||||
|
||||
```jsx
|
||||
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';
|
||||
|
||||
const config = {
|
||||
pluginSlots: {
|
||||
'org.openedx.frontend.layout.footer.v1': {
|
||||
plugins: [
|
||||
{
|
||||
// Hide the default footer
|
||||
op: PLUGIN_OPERATIONS.Hide,
|
||||
widgetId: 'default_contents',
|
||||
},
|
||||
{
|
||||
// Insert a custom footer
|
||||
op: PLUGIN_OPERATIONS.Insert,
|
||||
widget: {
|
||||
id: 'custom_footer',
|
||||
type: DIRECT_PLUGIN,
|
||||
RenderWidget: () => (
|
||||
<h1 style={{textAlign: 'center'}}>🦶</h1>
|
||||
),
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default config;
|
||||
```
|
||||
BIN
src/plugin-slots/FooterSlot/images/custom_footer.png
Normal file
BIN
src/plugin-slots/FooterSlot/images/custom_footer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
BIN
src/plugin-slots/FooterSlot/images/default_footer.png
Normal file
BIN
src/plugin-slots/FooterSlot/images/default_footer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
14
src/plugin-slots/FooterSlot/index.jsx
Normal file
14
src/plugin-slots/FooterSlot/index.jsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import { PluginSlot } from '@openedx/frontend-plugin-framework';
|
||||
import Footer from '../../components/Footer';
|
||||
|
||||
const FooterSlot = () => (
|
||||
<PluginSlot
|
||||
id="org.openedx.frontend.layout.footer.v1"
|
||||
idAliases={['footer_slot', 'footer_plugin_slot']}
|
||||
>
|
||||
<Footer />
|
||||
</PluginSlot>
|
||||
);
|
||||
|
||||
export default FooterSlot;
|
||||
@@ -1,3 +1,5 @@
|
||||
# `frontend-component-footer` Plugin Slots
|
||||
|
||||
* [`studio_footer_logo_slot`](./StudioFooterLogoSlot/)
|
||||
* [`org.openedx.frontend.layout.footer.v1`](./FooterSlot/)
|
||||
* [`org.openedx.frontend.layout.studio_footer.v1`](./StudioFooterSlot/)
|
||||
* [`org.openedx.frontend.layout.studio_footer_logo.v1`](./StudioFooterLogoSlot/)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# StudioFooterLogo Slot
|
||||
# StudioFooterLogoSlot
|
||||
|
||||
### Slot ID: `studio_footer_logo_slot`
|
||||
### Slot ID: `org.openedx.frontend.layout.studio_footer_logo.v1`
|
||||
|
||||
### Slot ID Aliases
|
||||
* `studio_footer_logo_slot`
|
||||
|
||||
## Description
|
||||
|
||||
@@ -23,13 +26,13 @@ import {
|
||||
|
||||
const config = {
|
||||
pluginSlots: {
|
||||
studio_footer_logo_slot: {
|
||||
'org.openedx.frontend.layout.studio_footer_logo.v1': {
|
||||
keepDefault: true,
|
||||
plugins: [
|
||||
{
|
||||
op: PLUGIN_OPERATIONS.Insert,
|
||||
widget: {
|
||||
id: 'studio_footer_logo_slot',
|
||||
id: 'studio_footer_logo_addition',
|
||||
type: DIRECT_PLUGIN,
|
||||
priority: 40,
|
||||
RenderWidget: () => {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { PluginSlot } from '@openedx/frontend-plugin-framework';
|
||||
import { Hyperlink, Image } from '@openedx/paragon';
|
||||
|
||||
const StudioFooterLogoSlot = () => (
|
||||
<PluginSlot id="studio_footer_logo_slot">
|
||||
<PluginSlot id="org.openedx.frontend.layout.studio_footer_logo.v1" idAliases={['studio_footer_logo_slot']}>
|
||||
<Hyperlink destination="https://openedx.org" className="float-right">
|
||||
<Image
|
||||
width="120px"
|
||||
|
||||
51
src/plugin-slots/StudioFooterSlot/README.md
Normal file
51
src/plugin-slots/StudioFooterSlot/README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# StudioFooterSlot
|
||||
|
||||
### Slot ID: `org.openedx.frontend.layout.studio_footer.v1`
|
||||
|
||||
### Slot ID Aliases
|
||||
* `studio_footer_slot`
|
||||
|
||||
## Description
|
||||
|
||||
This slot is used to repace/modify/hide the entire studio footer.
|
||||
|
||||
## Example
|
||||
|
||||
The following `env.config.jsx` will replace the default studio footer.
|
||||
|
||||

|
||||
|
||||
with a simple custom footer
|
||||
|
||||

|
||||
|
||||
```jsx
|
||||
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';
|
||||
|
||||
const config = {
|
||||
pluginSlots: {
|
||||
'org.openedx.frontend.layout.studio_footer.v1': {
|
||||
plugins: [
|
||||
{
|
||||
// Hide the default footer
|
||||
op: PLUGIN_OPERATIONS.Hide,
|
||||
widgetId: 'default_contents',
|
||||
},
|
||||
{
|
||||
// Insert a custom footer
|
||||
op: PLUGIN_OPERATIONS.Insert,
|
||||
widget: {
|
||||
id: 'custom_footer',
|
||||
type: DIRECT_PLUGIN,
|
||||
RenderWidget: () => (
|
||||
<h1 style={{textAlign: 'center'}}>🦶</h1>
|
||||
),
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default config;
|
||||
```
|
||||
BIN
src/plugin-slots/StudioFooterSlot/images/custom_footer.png
Normal file
BIN
src/plugin-slots/StudioFooterSlot/images/custom_footer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 79 KiB |
11
src/plugin-slots/StudioFooterSlot/index.jsx
Normal file
11
src/plugin-slots/StudioFooterSlot/index.jsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
import { PluginSlot } from '@openedx/frontend-plugin-framework';
|
||||
import StudioFooter from '../../components/studio-footer';
|
||||
|
||||
const StudioFooterSlot = () => (
|
||||
<PluginSlot id="org.openedx.frontend.layout.studio_footer.v1" idAliases={['studio_footer_slot']}>
|
||||
<StudioFooter />
|
||||
</PluginSlot>
|
||||
);
|
||||
|
||||
export default StudioFooterSlot;
|
||||
Reference in New Issue
Block a user