Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add username slots #560

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions src/desktop-header/DesktopHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { getConfig } from '@edx/frontend-platform';

// Local Components
import { Menu, MenuTrigger, MenuContent } from '../Menu';
import Avatar from '../Avatar';
import LogoSlot from '../plugin-slots/LogoSlot';
import DesktopLoggedOutItemsSlot from '../plugin-slots/DesktopLoggedOutItemsSlot';
import { desktopLoggedOutItemsDataShape } from './DesktopLoggedOutItems';
Expand All @@ -14,13 +13,11 @@ import { desktopHeaderMainOrSecondaryMenuDataShape } from './DesktopHeaderMainOr
import DesktopSecondaryMenuSlot from '../plugin-slots/DesktopSecondaryMenuSlot';
import DesktopUserMenuSlot from '../plugin-slots/DesktopUserMenuSlot';
import { desktopUserMenuDataShape } from './DesktopHeaderUserMenu';
import DesktopUsernameSlot from '../plugin-slots/DesktopUsernameSlot';

// i18n
import messages from '../Header.messages';

// Assets
import { CaretIcon } from '../Icons';

class DesktopHeader extends React.Component {
constructor(props) { // eslint-disable-line no-useless-constructor
super(props);
Expand Down Expand Up @@ -51,8 +48,7 @@ class DesktopHeader extends React.Component {
aria-label={intl.formatMessage(messages['header.label.account.menu.for'], { username })}
className="btn btn-outline-primary d-inline-flex align-items-center pl-2 pr-3"
>
<Avatar size="1.5em" src={avatar} alt="" className="mr-2" />
{username} <CaretIcon role="img" aria-hidden focusable="false" />
<DesktopUsernameSlot username={username} avatar={avatar} />
</MenuTrigger>
<MenuContent className="mb-0 dropdown-menu show dropdown-menu-right pin-right shadow py-2">
<DesktopUserMenuSlot menu={userMenu} />
Expand Down
8 changes: 2 additions & 6 deletions src/learning-header/AuthenticatedUserDropdown.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import React from 'react';
import PropTypes from 'prop-types';

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faUserCircle } from '@fortawesome/free-solid-svg-icons';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { Dropdown } from '@openedx/paragon';

import LearningUserMenuSlot from '../plugin-slots/LearningUserMenuSlot';
import LearningUsernameSlot from '../plugin-slots/LearningUsernameSlot';

import messages from './messages';

Expand Down Expand Up @@ -38,10 +37,7 @@ const AuthenticatedUserDropdown = ({ intl, username }) => {
return (
<Dropdown className="user-dropdown ml-3">
<Dropdown.Toggle variant="outline-primary">
<FontAwesomeIcon icon={faUserCircle} className="d-md-none" size="lg" />
<span data-hj-suppress className="d-none d-md-inline">
{username}
</span>
<LearningUsernameSlot username={username} />
</Dropdown.Toggle>
<Dropdown.Menu className="dropdown-menu-right">
<LearningUserMenuSlot items={dropdownItems} />
Expand Down
116 changes: 116 additions & 0 deletions src/plugin-slots/DesktopUsernameSlot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Desktop Username Slot

### Slot ID: `desktop_username_slot`

## Description

This slot is used to replace/modify/hide the desktop username.

## Examples

### Modify Username

The following `env.config.jsx` will modify the username (in this case replacing it with 🤠)

![Screenshot of modified username](./images/desktop_username_modified.png)

```jsx
import { PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';

const modifyUsername = ( widget ) => {
widget.content.username = "🤠";
return widget;
};

const config = {
pluginSlots: {
desktop_username_slot: {
keepDefault: true,
plugins: [
{
op: PLUGIN_OPERATIONS.Modify,
widgetId: 'default_contents',
fn: modifyUsername,
},
]
},
},
}

export default config;
```


### Replace Username with Custom Component

The following `env.config.jsx` will replace the items in the desktop username entirely (in this case with an svg circle)

![Screenshot of replaced with custom component](./images/desktop_username_custom_component.png)

```jsx
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';

const config = {
pluginSlots: {
desktop_username_slot: {
keepDefault: false,
plugins: [
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'custom_username_component',
type: DIRECT_PLUGIN,
RenderWidget: () => (
<svg height="30" width="30">
<circle r="15" cx="15" cy="15" fill="purple" />
</svg>
),
},
},
]
},
},
}

export default config;
```

### Add Custom Components before and after Username

The following `env.config.jsx` will place custom components before and after the desktop username (in this case 🖋️ and 🪄).

![Screenshot of custom components before and after](./images/desktop_username_custom_components_before_after.png)

```jsx
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';

const config = {
pluginSlots: {
desktop_username_slot: {
keepDefault: true,
plugins: [
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'custom_before_username_component',
type: DIRECT_PLUGIN,
priority: 10,
RenderWidget: () => "🖋️",
},
},
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'custom_after_username_component',
type: DIRECT_PLUGIN,
priority: 90,
RenderWidget: () => "🪄",
},
},
]
},
},
}

export default config;
```
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions src/plugin-slots/DesktopUsernameSlot/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import PropTypes from 'prop-types';
import { PluginSlot } from '@openedx/frontend-plugin-framework';

import Avatar from '../../Avatar';
import { CaretIcon } from '../../Icons';

const DesktopUsername = ({ username, avatar }) => (
<>
<Avatar size="1.5em" src={avatar} alt="" className="mr-2" />
{username} <CaretIcon role="img" aria-hidden focusable="false" />
</>
);

const DesktopUsernameSlot = ({ username, avatar }) => (
<PluginSlot
id="desktop_username_slot"
slotOptions={{
mergeProps: true,
}}
>
<DesktopUsername username={username} avatar={avatar} />
</PluginSlot>
);

DesktopUsername.propTypes = {
avatar: PropTypes.string,
username: PropTypes.string.isRequired,
};

DesktopUsername.defaultProps = {
avatar: null,
};

DesktopUsernameSlot.propTypes = DesktopUsername.propTypes;
DesktopUsernameSlot.defaultProps = DesktopUsername.defaultProps;

export default DesktopUsernameSlot;
116 changes: 116 additions & 0 deletions src/plugin-slots/LearningUsernameSlot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Learning Username Slot

### Slot ID: `learning_username_slot`

## Description

This slot is used to replace/modify/hide the learning username.

## Examples

### Modify Username

The following `env.config.jsx` will modify the username (in this case replacing it with 🤠)

![Screenshot of modified username](./images/learning_username_modified.png)

```jsx
import { PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';

const modifyUsername = ( widget ) => {
widget.content.username = "🤠";
return widget;
};

const config = {
pluginSlots: {
learning_username_slot: {
keepDefault: true,
plugins: [
{
op: PLUGIN_OPERATIONS.Modify,
widgetId: 'default_contents',
fn: modifyUsername,
},
]
},
},
}

export default config;
```


### Replace Username with Custom Component

The following `env.config.jsx` will replace the items in the learning username entirely (in this case with an svg circle)

![Screenshot of replaced with custom component](./images/learning_username_custom_component.png)

```jsx
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';

const config = {
pluginSlots: {
learning_username_slot: {
keepDefault: false,
plugins: [
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'custom_username_component',
type: DIRECT_PLUGIN,
RenderWidget: () => (
<svg height="30" width="30">
<circle r="15" cx="15" cy="15" fill="purple" />
</svg>
),
},
},
]
},
},
}

export default config;
```

### Add Custom Components before and after Username

The following `env.config.jsx` will place custom components before and after the learning username (in this case 🖋️ and 🪄).

![Screenshot of custom components before and after](./images/learning_username_custom_components_before_after.png)

```jsx
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';

const config = {
pluginSlots: {
learning_username_slot: {
keepDefault: true,
plugins: [
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'custom_before_username_component',
type: DIRECT_PLUGIN,
priority: 10,
RenderWidget: () => "🖋️",
},
},
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'custom_after_username_component',
type: DIRECT_PLUGIN,
priority: 90,
RenderWidget: () => "🪄",
},
},
]
},
},
}

export default config;
```
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 33 additions & 0 deletions src/plugin-slots/LearningUsernameSlot/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import PropTypes from 'prop-types';
import { PluginSlot } from '@openedx/frontend-plugin-framework';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faUserCircle } from '@fortawesome/free-solid-svg-icons';

const LearningUsername = ({ username }) => (
<>
<FontAwesomeIcon icon={faUserCircle} className="d-md-none" size="lg" />
<span data-hj-suppress className="d-none d-md-inline">
{username}
</span>
</>
);

const LearningUsernameSlot = ({ username }) => (
<PluginSlot
id="learning_username_slot"
slotOptions={{
mergeProps: true,
}}
>
<LearningUsername username={username} />
</PluginSlot>
);

LearningUsername.propTypes = {
username: PropTypes.string.isRequired,
};

LearningUsernameSlot.propTypes = LearningUsername.propTypes;

export default LearningUsernameSlot;
2 changes: 2 additions & 0 deletions src/plugin-slots/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
* [`desktop_logged_out_items_slot`](./DesktopLoggedOutItemsSlot/)
* [`mobile_logged_out_items_slot`](./MobileLoggedOutItemsSlot/)
* [`mobile_user_menu_slot`](./MobileUserMenuSlot/)
* [`desktop_username_slot`](./DesktopUsernameSlot/)
* [`desktop_user_menu_slot`](./DesktopUserMenuSlot/)
* [`learning_username_slot`](./LearningUsernameSlot/)
* [`learning_user_menu_slot`](./LearningUserMenuSlot/)
* [`learning_logged_out_items_slot`](./LearningLoggedOutItemsSlot/)
* [`desktop_header_slot`](./DesktopHeaderSlot/)
Loading