-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(WebexMemberRoster): split component into members roster and meet…
…ing roster
- Loading branch information
1 parent
d1edde8
commit 6827327
Showing
10 changed files
with
686 additions
and
512 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
107 changes: 107 additions & 0 deletions
107
src/components/WebexMeetingRoster/WebexMeetingRoster.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import {DestinationType} from '@webex/component-adapter-interfaces'; | ||
import webexComponentClasses from '../helpers'; | ||
|
||
import Button from '../generic/Button/Button'; | ||
import Icon from '../generic/Icon/Icon'; | ||
import Title from '../generic/Title/Title'; | ||
import useMembers from '../hooks/useMembers'; | ||
import {useMe} from '../hooks'; | ||
import WebexMeetingParticipant from '../WebexMeetingParticipant/WebexMeetingParticipant'; | ||
|
||
// TODO: Figure out how to import JS Doc definitions and remove duplication. | ||
/** | ||
* Enum for types of destinations. | ||
* | ||
* @external DestinationType | ||
* @see {@link https://github.com/webex/component-adapter-interfaces/blob/master/src/MembershipsAdapter.js#L21} | ||
*/ | ||
|
||
/** | ||
* Displays the roster of Webex meeting. | ||
* | ||
* @param {object} props Data passed to the component | ||
* @param {string} props.className Custom CSS class to apply | ||
* @param {string} props.meetingID ID of the meeting for which to get members | ||
* @param {object} props.style Custom style to apply | ||
* @param {Function} props.onClose Action to close the roster | ||
* @returns {object} JSX of the component | ||
* | ||
*/ | ||
export default function WebexMeetingRoster({ | ||
className, | ||
meetingID, | ||
style, | ||
onClose, | ||
}) { | ||
const members = useMembers(meetingID, DestinationType.MEETING); | ||
const {orgID} = useMe(); | ||
|
||
const [cssClasses, sc] = webexComponentClasses('meeting-roster', className); | ||
|
||
const renderMembers = (data) => data.map( | ||
({ID}) => ( | ||
<WebexMeetingParticipant | ||
meetingID={meetingID} | ||
personID={ID} | ||
key={ID} | ||
/> | ||
), | ||
); | ||
|
||
const renderSection = (data, title) => data.length > 0 && ( | ||
<> | ||
<h5 className={sc('section-title')}>{title}</h5> | ||
{renderMembers(data)} | ||
</> | ||
); | ||
|
||
const warningExternalMembers = members.some( | ||
(member) => member.orgID !== undefined && orgID !== undefined && member.orgID !== orgID, | ||
) && ( | ||
<div className={sc('external-user-warning')}> | ||
<Icon name="external-user" size={20} className={sc('external-user-icon')} /> | ||
<div className={sc('external-user-message')}>People outside your company are included in this space</div> | ||
</div> | ||
); | ||
|
||
return ( | ||
<div className={cssClasses} style={style}> | ||
<div className={sc('header')}> | ||
<Title type="section" className={sc('title')}> | ||
Participants ( | ||
{members ? members.length : <i>loading...</i>} | ||
) | ||
</Title> | ||
<Button | ||
type="ghost" | ||
size={28} | ||
onClick={onClose} | ||
tabIndex={50} | ||
ariaLabel="Close participants panel" | ||
> | ||
<Icon name="cancel" size={16} /> | ||
</Button> | ||
</div> | ||
{warningExternalMembers} | ||
<div className={sc('members')}> | ||
{renderSection(members.filter((member) => member.inMeeting), 'In the meeting')} | ||
{renderSection(members.filter((member) => !member.inMeeting), 'Not in the meeting')} | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
WebexMeetingRoster.propTypes = { | ||
className: PropTypes.string, | ||
meetingID: PropTypes.string.isRequired, | ||
style: PropTypes.shape(), | ||
onClose: PropTypes.func, | ||
}; | ||
|
||
WebexMeetingRoster.defaultProps = { | ||
className: '', | ||
style: undefined, | ||
onClose: undefined, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
$C: #{$WEBEX_COMPONENTS_CLASS_PREFIX}-meeting-roster; | ||
|
||
.#{$C} { | ||
display: flex; | ||
flex-direction: column; | ||
|
||
color: var(--wxc-text-color); | ||
background: var(--wxc-secondary-background); | ||
border-radius: 0.5rem 0 0 0; | ||
padding: 0.625rem 0 0.625rem 0.75rem; | ||
|
||
|
||
.#{$C}__section-title { | ||
color: var(--wxc-secondary-text-color); | ||
font-size: 0.875rem; | ||
line-height: 1.375rem; | ||
margin: 0; | ||
letter-spacing: normal; | ||
padding: 0.438rem 0 0.188rem 0; | ||
} | ||
|
||
.#{$C}__external-user-warning { | ||
color: var(--wxc-warning-color); | ||
display: flex; | ||
align-items: flex-start; | ||
font-size: 0.875rem; | ||
line-height: 1.375rem; | ||
margin-top: 0.75rem; | ||
|
||
.#{$C}__external-user-icon { | ||
margin-right: 0.578rem; | ||
} | ||
|
||
.#{$C}__external-user-message { | ||
flex: 1; | ||
} | ||
} | ||
|
||
.#{$C}__header { | ||
display: flex; | ||
align-items: center; | ||
padding-right: 0.375rem; | ||
|
||
.#{$C}__title { | ||
font-family: $brand-font-bold; | ||
margin: 0; | ||
flex: 1; | ||
} | ||
} | ||
|
||
.#{$C}__members { | ||
overflow-y: auto; | ||
flex: 1; | ||
padding-right: 1.25rem; | ||
scrollbar-width: thin; //works only for Firefox | ||
} | ||
|
||
::-webkit-scrollbar { | ||
width: 1rem; | ||
} | ||
|
||
::-webkit-scrollbar-thumb { | ||
background: var(--wxc-scrollbar--thumb); | ||
border-radius: 1rem; | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
src/components/WebexMeetingRoster/WebexMeetingRoster.stories.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import React from 'react'; | ||
import WebexMeetingRoster from './WebexMeetingRoster'; | ||
|
||
export default { | ||
title: 'Meetings/Webex Meeting Roster', | ||
component: WebexMeetingRoster, | ||
}; | ||
|
||
const Template = (args) => { | ||
const style = { | ||
width: '23.25rem', | ||
maxHeight: '100%', | ||
...args.style, | ||
}; | ||
const props = {...args, style}; | ||
|
||
return <WebexMeetingRoster {...props} />; | ||
}; | ||
|
||
export const Meeting = Template.bind({}); | ||
Meeting.args = { | ||
meetingID: 'meeting2', | ||
}; |
Oops, something went wrong.