diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/component.jsx index a63f158a7af19c61f670be5158f322884a2923f8..006e364b0b55e68f58176f1163892d6b45121e32 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/component.jsx @@ -155,6 +155,7 @@ class BreakoutRoom extends PureComponent { this.blurDurationTime = this.blurDurationTime.bind(this); this.removeRoomUsers = this.removeRoomUsers.bind(this); this.renderErrorMessages = this.renderErrorMessages.bind(this); + this.renderJoinedUsers = this.renderJoinedUsers.bind(this); this.state = { numberOfRooms: MIN_BREAKOUT_ROOMS, @@ -168,17 +169,23 @@ class BreakoutRoom extends PureComponent { valid: true, record: false, numberOfRoomsIsValid: true, + breakoutJoinedUsers: null, }; this.btnLevelId = _.uniqueId('btn-set-level-'); } componentDidMount() { - const { isInvitation } = this.props; + const { isInvitation, breakoutJoinedUsers } = this.props; this.setRoomUsers(); if (isInvitation) { this.setInvitationConfig(); } + if (isInvitation) { + this.setState({ + breakoutJoinedUsers, + }); + } } componentDidUpdate(prevProps, prevstate) { @@ -318,6 +325,12 @@ class BreakoutRoom extends PureComponent { return users.filter(user => user.room === room); } + getUsersByRoomSequence(sequence) { + const { breakoutJoinedUsers } = this.state; + if (!breakoutJoinedUsers) return []; + return breakoutJoinedUsers.filter(room => room.sequence === sequence)[0].joinedUsers || []; + } + removeRoomUsers() { const { users } = this.props; const { users: stateUsers } = this.state; @@ -392,7 +405,7 @@ class BreakoutRoom extends PureComponent { } renderRoomsGrid() { - const { intl } = this.props; + const { intl, isInvitation } = this.props; const { valid, numberOfRooms, @@ -432,6 +445,7 @@ class BreakoutRoom extends PureComponent { </p> <div className={styles.breakoutBox} onDrop={drop(value)} onDragOver={allowDrop}> {this.renderUserItemByRoom(value)} + {isInvitation && this.renderJoinedUsers(value)} </div> </div> )) @@ -551,12 +565,16 @@ class BreakoutRoom extends PureComponent { const { users, roomSelected, + breakoutJoinedUsers, } = this.state; + const { isInvitation } = this.props; + return ( <SortList confirm={() => this.setState({ formFillLevel: 2 })} users={users} room={roomSelected} + breakoutJoinedUsers={isInvitation && breakoutJoinedUsers} onCheck={this.changeUserRoom} onUncheck={userId => this.changeUserRoom(userId, 0)} /> @@ -641,6 +659,25 @@ class BreakoutRoom extends PureComponent { </p>)); } + renderJoinedUsers(room) { + return this.getUsersByRoomSequence(room) + .map(user => ( + <p + id={user.userId} + key={user.userId} + disabled + className={cx( + styles.roomUserItem, + styles.disableItem, + ) + } + > + {user.name} + <span className={styles.lockIcon} /> + </p> + )); + } + renderRoomSortList() { const { intl, isInvitation } = this.props; const { numberOfRooms } = this.state; diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/container.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/container.jsx index 8c4ba7292c2b6cb36859f8e9e3cd18da15f9c4da..4f799b0b94d143abf64ede3cf39304a458cff04e 100644 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/container.jsx @@ -8,6 +8,7 @@ export default withTracker(() => ({ getBreakouts: ActionsBarService.getBreakouts, getUsersNotAssigned: ActionsBarService.getUsersNotAssigned, sendInvitation: ActionsBarService.sendInvitation, + breakoutJoinedUsers: ActionsBarService.breakoutJoinedUsers(), users: ActionsBarService.users(), meetingName: ActionsBarService.meetingName(), }))(CreateBreakoutRoomModal); diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/sort-user-list/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/sort-user-list/component.jsx index b0f9b49f98cf87f5df9b3b2dc615928dbab816c2..92c77b41621d2a32517c008ad47a71d1dec6a2fb 100644 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/sort-user-list/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/sort-user-list/component.jsx @@ -35,15 +35,19 @@ class SortUsers extends Component { this.setUsers = this.setUsers.bind(this); this.renderUserItem = this.renderUserItem.bind(this); this.onChage = this.onChage.bind(this); + this.renderJoinedUserItem = this.renderJoinedUserItem.bind(this); this.state = { users: [], + joinedUsers: [], }; } componentDidMount() { - const { users } = this.props; + const { users, breakoutJoinedUsers } = this.props; + this.setUsers(users); + this.setJoinedUsers(breakoutJoinedUsers); } onChage(userId, room) { @@ -64,6 +68,11 @@ class SortUsers extends Component { this.setState({ users: users.sort((a, b) => a.room - b.room) }); } + setJoinedUsers(users) { + if (!users) return; + this.setState({ joinedUsers: users.sort((a, b) => a.sequence - b.sequence) }); + } + renderUserItem() { const { room } = this.props; const { users } = this.state; @@ -93,6 +102,24 @@ class SortUsers extends Component { </div>)); } + renderJoinedUserItem() { + const { joinedUsers } = this.state; + if (!joinedUsers.length) return null; + + return joinedUsers + .map(b => b.joinedUsers.map(u => ({ ...u, room: b.sequence }))) + .flat() + .map(user => ( + <div className={styles.selectUserContainer}> + <span className={styles.lockIcon} /> + <span className={styles.textName}> + {user.name} + {`\t[${user.room}]`} + </span> + </div>)); + } + + render() { const { intl, @@ -114,6 +141,7 @@ class SortUsers extends Component { /> </header> {this.renderUserItem()} + {this.renderJoinedUserItem()} </div> ); } diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/styles.scss b/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/styles.scss index 47c141622f15b762d054d61515ca83c92e00b6e8..50b1d986040ae25747ddb6909ab9deecf0840969 100644 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/styles.scss +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/create-breakout-room/styles.scss @@ -160,13 +160,13 @@ input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-i } .roomUserItem { - width: 11rem; margin: 0; padding: .25rem 0 .25rem .25rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; + border-bottom: solid .5px var(--color-gray-lighter); [dir="rtl"] & { padding: .25rem .25rem .25rem 0; @@ -343,4 +343,24 @@ input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-i .errorBorder { border-color: var(--color-danger) !important; -} \ No newline at end of file +} + +.disableItem { + cursor: not-allowed; + color: var(--color-gray-lighter); +} + +.lockIcon { + float: right; + margin-right: 1rem; + @include mq($small-only) { + margin-left: .5rem; + margin-right: auto; + float: left; + } + &:after { + font-family: 'bbb-icons'; + content: "\E926"; + color: var(--color-gray-light); + } +} diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/service.js b/bigbluebutton-html5/imports/ui/components/actions-bar/service.js index 20960bf10cf39ce9ed2e1cfb657d942ebce0f455..b2aff808df014a01e431c87b8af33bf62a3b4e8d 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/service.js +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/service.js @@ -42,6 +42,9 @@ export default { toggleRecording: () => makeCall('toggleRecording'), createBreakoutRoom: (numberOfRooms, durationInMinutes, record = false) => makeCall('createBreakoutRoom', numberOfRooms, durationInMinutes, record), sendInvitation: (breakoutId, userId) => makeCall('requestJoinURL', { breakoutId, userId }), + breakoutJoinedUsers: () => Breakouts.find({ + joinedUsers: { $exists: true }, + }, { fields: { joinedUsers: 1, breakoutId: 1, sequence: 1 }, sort: { sequence: 1 } }).fetch(), getBreakouts, getUsersNotAssigned, takePresenterRole,