Compare commits

..

24 Commits

Author SHA1 Message Date
Sébastien Marinier 98640de1b3
Merge b3fd04b2ae into 038f24302f 2024-08-23 10:39:52 +02:00
Sébastien Marinier b3fd04b2ae
Merge branch 'master' into feature/share_moderators_and_users 2024-08-23 10:39:48 +02:00
Nextcloud bot 038f24302f
Fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2024-08-22 02:22:13 +00:00
Sebastien Marinier f57c25eab2 fix: no clone action for non-admin
clone room only for admins
2024-08-19 12:26:23 +02:00
Sebastien Marinier bcf33e99e9 style: respect tabs
use 2 spaces
2024-08-19 12:25:09 +02:00
Sebastien Marinier e34c3b6e9e style: disabled checkbox
make disabled checkbox as nextcloud
2024-08-19 12:20:37 +02:00
Sebastien Marinier b099136690 feat: sharing rooms with moderators and users
Dialog and permissions management
2024-08-19 11:43:37 +02:00
Sebastien Marinier 7f1760c372 feat: manage view of rooms for moderators and users 2024-08-19 11:41:29 +02:00
Sebastien Marinier ab314393e9 fix: bug with name of shared groups
Shared groups were listed with their ID and not their display name
2024-08-19 11:23:25 +02:00
Sebastien Marinier a8591150de fix: don't use backticks
Use concatenated strings
2024-08-19 11:18:56 +02:00
Sebastien Marinier 858753022b feat: videos for all users and moderators
Users and moderators recording views
2024-08-17 11:50:09 +02:00
Sebastien Marinier 558cc95231 feat: sharing rooms with moderators and users
Dialog and permissions management
2024-08-17 11:47:11 +02:00
Sebastien Marinier 4095cbe52d feat: manage view of rooms for moderators and users 2024-08-16 12:49:12 +02:00
Sebastien Marinier 2a29608c97 fix: 261 remove some backticks
remove backticks interfering with xgettext translations sentences extraction
2024-08-16 12:46:57 +02:00
Nextcloud bot fbb4ae1cf3 Fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2024-08-16 12:45:09 +02:00
Nextcloud bot 57a21b7c08 Fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2024-08-16 12:45:09 +02:00
Nextcloud bot f50a04063e Fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2024-08-16 12:45:09 +02:00
Nextcloud bot f853802777 Fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2024-08-16 12:45:09 +02:00
Sebastien Marinier 7744169037 fix: 261 wordings that aren't visible in Transifex
Let's try breaking the lines
2024-08-16 12:45:09 +02:00
Nextcloud bot ac8d23521f Fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2024-08-16 12:45:09 +02:00
Nextcloud bot 81e6c01ba1 Fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2024-08-16 12:45:09 +02:00
Nextcloud bot 35a764d13a Fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2024-08-16 12:45:09 +02:00
Thibaut 6ace431870
Merge pull request #284 from arawa/fix/261/missing_wordings_in_transifex_remove_backticks
fix: 261 remove some backticks
2024-08-16 09:02:29 +02:00
Sebastien Marinier 44a655835b fix: 261 remove some backticks
remove backticks interfering with xgettext translations sentences extraction
2024-08-15 15:42:55 +02:00
11 changed files with 70 additions and 38 deletions

View File

@ -18,6 +18,8 @@ OC.L10N.register(
"Access" : "Åtkomst", "Access" : "Åtkomst",
"Max" : "Max", "Max" : "Max",
"Edit" : "Redigera", "Edit" : "Redigera",
"This message is shown to all users in the chat area after they joined." : "Detta meddelande visas för alla användare i chattområdet efter att de gått med.",
"If enabled, the user list, chat area and presentation are hidden by default." : "Om aktiverat är användarlistan, chattområdet och presentationen dolda som standard.",
"Welcome" : "Välkommen", "Welcome" : "Välkommen",
"Miscellaneous" : "Diverse", "Miscellaneous" : "Diverse",
"Recording" : "Inspelning", "Recording" : "Inspelning",

View File

@ -16,6 +16,8 @@
"Access" : "Åtkomst", "Access" : "Åtkomst",
"Max" : "Max", "Max" : "Max",
"Edit" : "Redigera", "Edit" : "Redigera",
"This message is shown to all users in the chat area after they joined." : "Detta meddelande visas för alla användare i chattområdet efter att de gått med.",
"If enabled, the user list, chat area and presentation are hidden by default." : "Om aktiverat är användarlistan, chattområdet och presentationen dolda som standard.",
"Welcome" : "Välkommen", "Welcome" : "Välkommen",
"Miscellaneous" : "Diverse", "Miscellaneous" : "Diverse",
"Recording" : "Inspelning", "Recording" : "Inspelning",

View File

@ -11,6 +11,7 @@ use OCP\AppFramework\Controller;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\DataResponse;
use OCP\IGroupManager;
use OCP\IRequest; use OCP\IRequest;
use OCP\IUserManager; use OCP\IUserManager;
@ -24,6 +25,9 @@ class RoomShareController extends Controller {
/** @var IUserManager */ /** @var IUserManager */
private $userManager; private $userManager;
/** @var IGroupManager */
private $groupManager;
/** @var RoomService */ /** @var RoomService */
private $roomService; private $roomService;
@ -37,6 +41,7 @@ class RoomShareController extends Controller {
IRequest $request, IRequest $request,
RoomShareService $service, RoomShareService $service,
IUserManager $userManager, IUserManager $userManager,
IGroupManager $groupManager,
RoomService $roomService, RoomService $roomService,
CircleHelper $circleHelper, CircleHelper $circleHelper,
$userId $userId
@ -44,6 +49,7 @@ class RoomShareController extends Controller {
parent::__construct($appName, $request); parent::__construct($appName, $request);
$this->service = $service; $this->service = $service;
$this->userManager = $userManager; $this->userManager = $userManager;
$this->groupManager = $groupManager;
$this->roomService = $roomService; $this->roomService = $roomService;
$this->circleHelper = $circleHelper; $this->circleHelper = $circleHelper;
$this->userId = $userId; $this->userId = $userId;
@ -90,6 +96,14 @@ class RoomShareController extends Controller {
} }
$roomShare->setShareWithDisplayName($circle->getName()); $roomShare->setShareWithDisplayName($circle->getName());
} elseif ($roomShare->getShareType() === RoomShare::SHARE_TYPE_GROUP) {
$shareWithGroup = $this->groupManager->get($roomShare->getShareWith());
if ($shareWithGroup === null) {
continue;
}
$roomShare->setShareWithDisplayName($shareWithGroup->getDisplayName());
} }
$shares[] = $roomShare; $shares[] = $roomShare;

View File

@ -9,6 +9,7 @@ use OCA\BigBlueButton\Db\RoomShare;
use OCA\BigBlueButton\Service\RoomService; use OCA\BigBlueButton\Service\RoomService;
use OCA\BigBlueButton\Service\RoomShareService; use OCA\BigBlueButton\Service\RoomShareService;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\IGroupManager;
use OCP\IRequest; use OCP\IRequest;
use OCP\IUserManager; use OCP\IUserManager;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
@ -19,6 +20,7 @@ class RoomShareControllerTest extends TestCase {
private $roomService; private $roomService;
private $circleHelper; private $circleHelper;
private $userManager; private $userManager;
private $groupManager;
private $controller; private $controller;
private $userId = 'user_foo'; private $userId = 'user_foo';
@ -29,6 +31,7 @@ class RoomShareControllerTest extends TestCase {
$this->request = $this->createMock(IRequest::class); $this->request = $this->createMock(IRequest::class);
$this->service = $this->createMock(RoomShareService::class); $this->service = $this->createMock(RoomShareService::class);
$this->userManager = $this->createMock(IUserManager::class); $this->userManager = $this->createMock(IUserManager::class);
$this->groupManager = $this->createMock(IGroupManager::class);
$this->roomService = $this->createMock(RoomService::class); $this->roomService = $this->createMock(RoomService::class);
$this->circleHelper = $this->createMock(CircleHelper::class); $this->circleHelper = $this->createMock(CircleHelper::class);
@ -37,6 +40,7 @@ class RoomShareControllerTest extends TestCase {
$this->request, $this->request,
$this->service, $this->service,
$this->userManager, $this->userManager,
$this->groupManager,
$this->roomService, $this->roomService,
$this->circleHelper, $this->circleHelper,
$this->userId $this->userId

View File

@ -78,7 +78,7 @@ const ShareSelection: React.FC<Props> = (props) => {
className="suggestion" className="suggestion"
onMouseDown={preventOnBlurEvent} onMouseDown={preventOnBlurEvent}
onClick={() => selectShare(option)}> onClick={() => selectShare(option)}>
{option.label}{option.value.shareType === ShareType.Group ? ` (${t('bbb', 'Group')})` : ''} {option.label}{option.value.shareType === ShareType.Group ? ' (' + t('bbb', 'Group') + ')' : ''}
</li>); </li>);
}; };

View File

@ -161,8 +161,23 @@ pre {
.bbb-shrink { .bbb-shrink {
width: 44px; width: 44px;
white-space: nowrap; white-space: nowrap;
}
input[type="checkbox"]{
&+label:before {
border-radius: 3px;
border-width: 2px;
}
&:disabled+label:before {
opacity: .5;
}
&:not(input:checked):disabled+label:before {
background-color: transparent !important;
}
}
}
th { th {
padding: 14px 6px; padding: 14px 6px;

View File

@ -65,7 +65,7 @@ const EditRoomDialog: React.FC<Props> = ({ room, restriction, updateProperty, op
function inputElement(label: string, field: string, type: 'text' | 'number' = 'text') { function inputElement(label: string, field: string, type: 'text' | 'number' = 'text') {
return ( return (
<div className="bbb-form-element"> <div className="bbb-form-element">
<label htmlFor={`bbb-${field}`}> <label htmlFor={'bbb-' + field}>
<h3>{label}</h3> <h3>{label}</h3>
</label> </label>
@ -78,7 +78,7 @@ const EditRoomDialog: React.FC<Props> = ({ room, restriction, updateProperty, op
function selectElement(label: string, field: string, value: string, options: { [key: string]: string }, onChange: (value: string) => void) { function selectElement(label: string, field: string, value: string, options: { [key: string]: string }, onChange: (value: string) => void) {
return ( return (
<div className="bbb-form-element"> <div className="bbb-form-element">
<label htmlFor={`bbb-${field}`}> <label htmlFor={'bbb-' + field}>
<h3>{label}</h3> <h3>{label}</h3>
</label> </label>
@ -132,27 +132,27 @@ const EditRoomDialog: React.FC<Props> = ({ room, restriction, updateProperty, op
{room.access === Access.InternalRestricted && {room.access === Access.InternalRestricted &&
<div className="bbb-form-element bbb-form-shareWith"> <div className="bbb-form-element bbb-form-shareWith">
<span className="icon icon-details icon-visible"></span><em>{`${t('bbb', 'Access')} : ${descriptions.internalRestrictedShareWith}`}</em> <span className="icon icon-details icon-visible"></span><em>{t('bbb', 'Access') + ' : ' + descriptions.internalRestrictedShareWith}</em>
</div> </div>
} }
<div className="bbb-mt-1"> <div className="bbb-mt-1">
<input id={`bbb-everyoneIsModerator-${room.id}`} <input id={'bbb-everyoneIsModerator-' + room.id}
type="checkbox" type="checkbox"
className="checkbox" className="checkbox"
checked={room.everyoneIsModerator} checked={room.everyoneIsModerator}
onChange={(event) => updateProperty('everyoneIsModerator', event.target.checked)} /> onChange={(event) => updateProperty('everyoneIsModerator', event.target.checked)} />
<label htmlFor={`bbb-everyoneIsModerator-${room.id}`}>{t('bbb', 'Every participant is moderator')}</label> <label htmlFor={'bbb-everyoneIsModerator-' + room.id}>{t('bbb', 'Every participant is moderator')}</label>
</div> </div>
<em>{descriptions.moderator}</em> <em>{descriptions.moderator}</em>
<div className="bbb-mt-1"> <div className="bbb-mt-1">
<input id={`bbb-moderatorToken-${room.id}`} <input id={'bbb-moderatorToken-' + room.id}
type="checkbox" type="checkbox"
className="checkbox" className="checkbox"
checked={!!room.moderatorToken} checked={!!room.moderatorToken}
onChange={(event) => updateProperty('moderatorToken', event.target.checked ? 'true' : null)} /> onChange={(event) => updateProperty('moderatorToken', event.target.checked ? 'true' : null)} />
<label htmlFor={`bbb-moderatorToken-${room.id}`}>{t('bbb', 'Moderator access via URL')}</label> <label htmlFor={'bbb-moderatorToken-' + room.id}>{t('bbb', 'Moderator access via URL')}</label>
</div> </div>
{!!room.moderatorToken && <CopyToClipboard text={api.getRoomUrl(room, true)}><input type="text" readOnly={true} className="icon-clippy" value={api.getRoomUrl(room, true)} /></CopyToClipboard>} {!!room.moderatorToken && <CopyToClipboard text={api.getRoomUrl(room, true)}><input type="text" readOnly={true} className="icon-clippy" value={api.getRoomUrl(room, true)} /></CopyToClipboard>}
<em>{descriptions.moderatorToken}</em> <em>{descriptions.moderatorToken}</em>
@ -162,68 +162,68 @@ const EditRoomDialog: React.FC<Props> = ({ room, restriction, updateProperty, op
<h3>{t('bbb', 'Miscellaneous')}</h3> <h3>{t('bbb', 'Miscellaneous')}</h3>
<div> <div>
<div> <div>
<input id={`bbb-record-${room.id}`} <input id={'bbb-record-' + room.id}
type="checkbox" type="checkbox"
className="checkbox" className="checkbox"
checked={room.record} checked={room.record}
disabled={!restriction?.allowRecording} disabled={!restriction?.allowRecording}
onChange={(event) => updateProperty('record', event.target.checked)} /> onChange={(event) => updateProperty('record', event.target.checked)} />
<label htmlFor={`bbb-record-${room.id}`}>{t('bbb', 'Recording')}</label> <label htmlFor={'bbb-record-' + room.id}>{t('bbb', 'Recording')}</label>
</div> </div>
<p><em>{descriptions.recording}</em></p> <p><em>{descriptions.recording}</em></p>
</div> </div>
<div> <div>
<div> <div>
<input id={`bbb-requireModerator-${room.id}`} <input id={'bbb-requireModerator-' + room.id}
type="checkbox" type="checkbox"
className="checkbox" className="checkbox"
checked={room.requireModerator} checked={room.requireModerator}
onChange={(event) => updateProperty('requireModerator', event.target.checked)} /> onChange={(event) => updateProperty('requireModerator', event.target.checked)} />
<label htmlFor={`bbb-requireModerator-${room.id}`}>{t('bbb', 'Require moderator to start room')}</label> <label htmlFor={'bbb-requireModerator-' + room.id}>{t('bbb', 'Require moderator to start room')}</label>
</div> </div>
<p><em>{descriptions.requireModerator}</em></p> <p><em>{descriptions.requireModerator}</em></p>
</div> </div>
<div> <div>
<div> <div>
<input id={`bbb-listenOnly-${room.id}`} <input id={'bbb-listenOnly-' + room.id}
type="checkbox" type="checkbox"
className="checkbox" className="checkbox"
checked={room.listenOnly} checked={room.listenOnly}
onChange={(event) => updateProperty('listenOnly', event.target.checked)} /> onChange={(event) => updateProperty('listenOnly', event.target.checked)} />
<label htmlFor={`bbb-listenOnly-${room.id}`}>{t('bbb', 'Listen only option')}</label> <label htmlFor={'bbb-listenOnly-' + room.id}>{t('bbb', 'Listen only option')}</label>
</div> </div>
<p><em>{descriptions.listenOnly}</em></p> <p><em>{descriptions.listenOnly}</em></p>
</div> </div>
<div> <div>
<div> <div>
<input id={`bbb-mediaCheck-${room.id}`} <input id={'bbb-mediaCheck-' + room.id}
type="checkbox" type="checkbox"
className="checkbox" className="checkbox"
checked={!room.mediaCheck} checked={!room.mediaCheck}
onChange={(event) => updateProperty('mediaCheck', !event.target.checked)} /> onChange={(event) => updateProperty('mediaCheck', !event.target.checked)} />
<label htmlFor={`bbb-mediaCheck-${room.id}`}>{t('bbb', 'Skip media check before usage')}</label> <label htmlFor={'bbb-mediaCheck-' + room.id}>{t('bbb', 'Skip media check before usage')}</label>
</div> </div>
<p><em>{descriptions.mediaCheck}</em></p> <p><em>{descriptions.mediaCheck}</em></p>
</div> </div>
<div> <div>
<div> <div>
<input id={`bbb-cleanLayout-${room.id}`} <input id={'bbb-cleanLayout-' + room.id}
type="checkbox" type="checkbox"
className="checkbox" className="checkbox"
checked={room.cleanLayout} checked={room.cleanLayout}
onChange={(event) => updateProperty('cleanLayout', event.target.checked)} /> onChange={(event) => updateProperty('cleanLayout', event.target.checked)} />
<label htmlFor={`bbb-cleanLayout-${room.id}`}>{t('bbb', 'Clean layout')}</label> <label htmlFor={'bbb-cleanLayout-' + room.id}>{t('bbb', 'Clean layout')}</label>
</div> </div>
<p><em>{descriptions.cleanLayout}</em></p> <p><em>{descriptions.cleanLayout}</em></p>
</div> </div>
<div> <div>
<div> <div>
<input id={`bbb-joinMuted-${room.id}`} <input id={'bbb-joinMuted-' + room.id}
type="checkbox" type="checkbox"
className="checkbox" className="checkbox"
checked={room.joinMuted} checked={room.joinMuted}
onChange={(event) => updateProperty('joinMuted', event.target.checked)} /> onChange={(event) => updateProperty('joinMuted', event.target.checked)} />
<label htmlFor={`bbb-joinMuted-${room.id}`}>{t('bbb', 'Join meeting muted')}</label> <label htmlFor={'bbb-joinMuted-' + room.id}>{t('bbb', 'Join meeting muted')}</label>
</div> </div>
<p><em>{descriptions.joinMuted}</em></p> <p><em>{descriptions.joinMuted}</em></p>
</div> </div>

View File

@ -16,12 +16,12 @@ const RecordingRow: React.FC<Props> = ({recording, isAdmin, deleteRecording, sto
function checkPublished(recording: Recording, onChange: (value: boolean) => void) { function checkPublished(recording: Recording, onChange: (value: boolean) => void) {
return ( return (
<div> <div>
<input id={`bbb-record-state-${recording.id}`} <input id={'bbb-record-state-' + recording.id}
type="checkbox" type="checkbox"
className="checkbox" className="checkbox"
checked={recording.state === 'published'} checked={recording.state === 'published'}
onChange={(event) => onChange(event.target.checked)} /> onChange={(event) => onChange(event.target.checked)} />
<label htmlFor={`bbb-record-state-${recording.id}`}>{t('bbb', 'Published')}</label> <label htmlFor={'bbb-record-state-' + recording.id}>{t('bbb', 'Published')}</label>
</div> </div>
); );
} }

View File

@ -221,7 +221,7 @@ const RoomRow: React.FC<Props> = (props) => {
<tr className={showRecordings ? 'selected-row' : ''}> <tr className={showRecordings ? 'selected-row' : ''}>
<td className="start"> <td className="start">
<a href={api.getRoomUrl(room)} <a href={api.getRoomUrl(room)}
className={`button ${room.running ? 'success' : 'primary'}`} className={'button ' + (room.running ? 'success' : 'primary')}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
title={t('bbb', 'Open room')}> title={t('bbb', 'Open room')}>
@ -253,27 +253,22 @@ const RoomRow: React.FC<Props> = (props) => {
<td className="max-participants bbb-shrink"> <td className="max-participants bbb-shrink">
{edit('maxParticipants', 'number', adminRoom, {min: minParticipantsLimit, max: maxParticipantsLimit < 0 ? undefined : maxParticipantsLimit})} {edit('maxParticipants', 'number', adminRoom, {min: minParticipantsLimit, max: maxParticipantsLimit < 0 ? undefined : maxParticipantsLimit})}
</td> </td>
{adminRoom &&
<td className="record bbb-shrink"> <td className="record bbb-shrink">
<input id={`bbb-record-${room.id}`} type="checkbox" className="checkbox" disabled={!props.restriction?.allowRecording} checked={room.record} onChange={(event) => updateRoom('record', event.target.checked)} /> <input id={'bbb-record-' + room.id} type="checkbox" className="checkbox" disabled={!adminRoom || !props.restriction?.allowRecording} checked={room.record} onChange={(event) => updateRoom('record', event.target.checked)} />
<label htmlFor={`bbb-record-${room.id}`}></label> <label htmlFor={'bbb-record-' + room.id}></label>
</td> </td>
}
{!adminRoom &&
<td className="record bbb-shrink">
<span className={'icon '+(room.record ? 'icon-checkmark' : 'icon-close')+' icon-visible'}></span>
</td>
}
<td className="bbb-shrink"> <td className="bbb-shrink">
{<RecordingsNumber recordings={recordings} showRecordings={showRecordings} setShowRecordings={setShowRecordings} />} {<RecordingsNumber recordings={recordings} showRecordings={showRecordings} setShowRecordings={setShowRecordings} />}
</td> </td>
<td className="clone icon-col"> <td className="clone icon-col">
{adminRoom &&
<button <button
className="action-item" className="action-item"
onClick={cloneRow} onClick={cloneRow}
title={t('bbb', 'Clone room')}> title={t('bbb', 'Clone room')}>
<span className="icon icon-template-add icon-visible"></span> <span className="icon icon-template-add icon-visible"></span>
</button> </button>
}
</td> </td>
<td className="edit icon-col"> <td className="edit icon-col">
{adminRoom && {adminRoom &&

View File

@ -101,13 +101,13 @@ const ShareWith: React.FC<Props> = ({ room, permission, shares: allShares, setSh
return ( return (
<li key={share.id} className="bbb-shareWith__item"> <li key={share.id} className="bbb-shareWith__item">
<div className="avatardiv"> <div className="avatardiv">
{avatarUrl && <img src={avatarUrl} alt={`Avatar from ${displayName}`} />} {avatarUrl && <img src={avatarUrl} alt={'Avatar from ' + displayName} />}
{share.shareType === ShareType.Group && <span className="icon-group-white"></span>} {share.shareType === ShareType.Group && <span className="icon-group-white"></span>}
{share.shareType === ShareType.Circle && <span className="icon-circle-white"></span>} {share.shareType === ShareType.Circle && <span className="icon-circle-white"></span>}
</div> </div>
<div className="bbb-shareWith__item__label"> <div className="bbb-shareWith__item__label">
<h5>{displayName} <h5>{displayName}
{(share.id === ROOM_OWNER_ID || !isOwner) && ` (${permissionLabel(share.permission)})`} {(share.id === ROOM_OWNER_ID || !isOwner) && (' (' + permissionLabel(share.permission) + ')')}
</h5> </h5>
</div> </div>
{(share.id > ROOM_OWNER_ID && isOwner) && selectPermission(share.permission, (value) => { {(share.id > ROOM_OWNER_ID && isOwner) && selectPermission(share.permission, (value) => {

View File

@ -63,12 +63,12 @@ const RestrictionRoom: React.FC<Props> = (props) => {
<td className="record bbb-shrink"> <td className="record bbb-shrink">
<input <input
id={`bbb-record-${restriction.id}`} id={'bbb-record-' + restriction.id}
type="checkbox" type="checkbox"
className="checkbox" className="checkbox"
checked={restriction.allowRecording} checked={restriction.allowRecording}
onChange={(event) => updateRestriction('allowRecording', event.target.checked)} /> onChange={(event) => updateRestriction('allowRecording', event.target.checked)} />
<label htmlFor={`bbb-record-${restriction.id}`}></label> <label htmlFor={'bbb-record-' + restriction.id}></label>
</td> </td>
<td className="remove icon-col"> <td className="remove icon-col">