Skip to content

Commit

Permalink
feat(WebexMemberRoster): split component into members roster and meet…
Browse files Browse the repository at this point in the history
…ing roster
  • Loading branch information
thescripted committed Mar 30, 2022
1 parent d1edde8 commit 6827327
Show file tree
Hide file tree
Showing 10 changed files with 686 additions and 512 deletions.
3 changes: 2 additions & 1 deletion .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ export const parameters = {
'Platform',
[
'Webex Avatar',
'Webex Member Roster',
],
'Messaging',
[
'Webex Messaging',
'Webex Activity Stream',
'Webex Activity',
'Webex Member',
'Webex Member Roster',
],
'Meetings',
[
Expand All @@ -60,6 +60,7 @@ export const parameters = {
'Webex Remote Media',
'Webex Meeting Control',
'Webex Meeting Participant',
'Webex Meeting Roster',
],
],
},
Expand Down
107 changes: 107 additions & 0 deletions src/components/WebexMeetingRoster/WebexMeetingRoster.jsx
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,
};
66 changes: 66 additions & 0 deletions src/components/WebexMeetingRoster/WebexMeetingRoster.scss
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 src/components/WebexMeetingRoster/WebexMeetingRoster.stories.js
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',
};
Loading

0 comments on commit 6827327

Please sign in to comment.